您的位置:首页 > 其它

上海邀请赛2个题目

2011-08-18 10:59 204 查看
首先说一下DPJuice Extractor

这个DP要完成的就是区间转移,如果以水果为状态的话,无法满足无后效性,把时间离散化,然后用时间点作为状态设计DP。

然后如何转移减少复杂度,朴素的转移需要N^3的复杂度,方法为,计算第i时间切一道枚举j = (i - 1 至0)为前一刀,然后O(N)的计算区间内有多少的水果。

我们记录每个时间点之前出现的水果的位置,然后从该位置开始向前枚举于枚举迁移刀的时间同步,并且记录在这时间的水果结束时间大于等于i的个数,这样一来时间复杂度被均摊了……具体代码如下

UVA 12012

/*
* =====================================================================================
*
*       Filename:  sfx.cpp
*
*    Description:
*
*        Version:  1.0
*        Created:  08/18/2011 09:36:17 AM
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  ronaflx
*        Company:  hit-ACM-Group
*
* =====================================================================================
*/
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <iterator>
#include <limits>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <climits>
#include <algorithm>
#include <functional>
#include <numeric>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <list>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <stdexcept>
#include <utility>
#include <cassert>
#include <complex>
using namespace std;

#define LEFT(i) ((i) << 1)
#define RIGHT(i) (((i) << 1) | 1)
#define MID(i) ((l[i] + r[i]) >> 1)
#define CC(i, v) memset(i, v, sizeof(i))
#define REP(i, l, n) for(int i = l;i < int(n);++i)
#define FOREACH(con, i) for(__typeof(con.begin()) i = con.begin();i != con.end();++i)

typedef long long LL;
const int MAXN = 21000;
struct Sfx
{
int i;
int key[2];
bool operator < (const Sfx& s) const
{
return key[0] == s.key[0] ? key[1] < s.key[1] : key[0] < s.key[0];
}
} sfx[MAXN], temp[MAXN];
int rank[MAXN], bucket[MAXN], height[MAXN];// rank from 0 to n - 1
//基数排序,先拍第二关键字,再第一关键字
void radixSort(Sfx* in, int n, int idx, Sfx* out)
{
memset(bucket, 0, sizeof(int) * (n + 1));
for (int i = 0; i < n; i++)
bucket[in[i].key[idx]]++;
for (int i = 1; i <= n; i++)
bucket[i] += bucket[i - 1];
for (int i = n - 1; i >= 0; i--)//for down
out[--bucket[in[i].key[idx]]] = in[i];
}
void buildSA(const char* text, int n)
{
for (int i = 0; i < n; i++)
{
sfx[i].i = sfx[i].key[1] = i;
sfx[i].key[0] = text[i];
}
sort(sfx, sfx + n);
for (int i = 0; i < n; i++)//下面要比较,所以全变为0
sfx[i].key[1] = 0;
int wid = 1;
while (wid < n)
{
rank[sfx[0].i] = 0;
for (int i = 1; i < n; i++)
rank[sfx[i].i] = rank[sfx[i - 1].i] + (sfx[i - 1] < sfx[i]);
for (int i = 0; i < n; i++)
{
sfx[i].i = i;
sfx[i].key[0] = rank[i];
sfx[i].key[1] = i + wid < n ? rank[i + wid]: 0;
}
radixSort(sfx, n, 1, temp);
radixSort(temp, n, 0, sfx);
wid <<= 1;
}
}
void calHeight(const char* text, int* rank, int n)
{//h[i] = height[rank[i]], h[i] >= h[i - 1] - 1;
for(int i = 0;i < n;i++)
rank[sfx[i].i] = i;
for(int i = 0, k = 0, j; i < n; i++)
{
if (rank[i] == 0)
height[rank[i]] = 0;
else
{
if(k > 0) k-- ;
for (j = sfx[rank[i] - 1].i; text[i + k] == text[j + k];k++);
height[rank[i]] = k;
}
}
}
int RMQ[MAXN][20];
void buildRMQ(int n, int* height)
{
for(int i = 1;i <= n;i++) RMQ[i][0] = height[i - 1];
for (int j = 1; j <= log(n + 0.00) / log(2.0); j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
RMQ[i][j] = min(RMQ[i][j - 1], RMQ[i + (1 << (j - 1))][j - 1]);
}
int queryRMQ(int a, int b)
{
int len = log(b - a + 1.0) / log(2.0);
return min(RMQ[a][len], RMQ[b - (1 << len) + 1][len]);
}
int queryLCP(int a, int b)
{
a = rank[a] + 1;
b = rank[b] + 1;
if(a > b) swap(a, b);
return queryRMQ(a + 1, b);
}

char str[MAXN];
int ans[MAXN];
int main()
{
int t;
scanf("%d", &t);
for(int k = 1;k <= t;k++)
{
scanf("%s", str);
int n = strlen(str);
buildSA(str, n);
calHeight(str, rank, n);
buildRMQ(n, height);
memset(ans, 0, sizeof(ans));
ans[1] = n;
for(int i = 0;i < n;i++)
{
int len = n - i;
for(int j = 1;j < len;j++)
{
int tmp = queryLCP(i, i + j);
int c = tmp / j + 1;
for(int cc = 1;cc <= c;cc++)
ans[cc] = max(ans[cc], cc * j);
}
}
printf("Case #%d: ", k);
for(int i = 1;i <= n;i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: