将自己历史的AC共享
zoj3161 DP题
dp[i] = max( min(dp[j-1]+dp[i-j],dp[j]+dp[i-j-1]),1<=j< i )
//1767788 2009-02-20 10:53:25 Accepted 3161 C++ 100 1176 green tea
#include <cstdio>
#include <algorithm>
using namespace std;
//当确定出一个情侣的序列时,会员们会尽最大的努力使跑掉的人最多。问题是帮管家确定一个序列,使留下来的人最多。
//假设有 i 个连续的人,每相邻两个都有 8g 关系,管家给出一个序列使留下最多 dp[i] 个人
//管家给出的第一个序列可能是 (j, j + 1) 这时第 j 个人或许第 j+1 个人会跑掉. 留下的人为 dp[j-1] + dp[i-j]
//或dp[j] + dp[i-j-1]. 取其中小的一个。枚举 j 的位置 可得到 dp[i] 的最大值。
int n, m;
int a[505][505], dp[505], f[505];
void Dp() {
int i, j, temp;
dp[0] = 0;
dp[1] = dp[2] = dp[3] = 1;
for ( i = 4; i <= 500; ++i ) {
dp[i] = 0;
for ( j = 1; j < i; ++j ) {
temp = min(dp[j-1]+dp[i-j], dp[j]+dp[i-j-1]);
if ( temp > dp[i] ) dp[i] = temp;
}
}
}
int main()
{
int i;
while ( scanf("%d%d", &n, &m) != EOF ) {
int s, e;
Dp();
memset(a, 0, sizeof(a));
memset(f, 0, sizeof(f));
for ( i = 0; i < m; ++i ) {
scanf("%d%d", &s, &e);
a[s][e] = a[e][s] = 1;
}
int res = 0, k = 0;
for ( i = 0; i < n-1; ++i ) {
if ( k == 0 && a[i][i+1] == 1 ) { k+=2;f[i]=f[i+1]=1; }
else if ( a[i][i+1] == 1 ) { k++;f[i]=f[i+1]=1; }
else {
res += dp[k];
k = 0;
}
}
res += dp[k];
for ( i = 0; i < n; ++i )
if ( f[i] == 0 ) res++;
printf("%d\n", res);
}
return 0;
}
如觉得还有问题 可参考其他相关文章
zoj3161 其他1
zoj3161 其他2
zoj3161 其他3
zoj3161 其他1