TYVJ 1078 删数 解题报告
刚开始还以为和那个硬币游戏一样,要用那种DP,然后我想破脑袋想不出来,后来看了题解才知道就是区间动态规划,那就简单了,方程我不写了,我的还有条件,麻烦得很,看代码里面吧。
对比了一下硬币游戏和这题,小感悟:如果是两人或多人的博弈游戏,那状态里就要有上回对方是怎么取舍的;但是如果只是自己去,那就是区间动态规划。
代码:
#include <stdio.h>
#include <stdlib.h>
#define max(a, b) ((a)>(b)?(a):(b))
int num[100];
int f[101][101];
//f[i][j] 表示从i到j最大取得数
int dp(int start, int end)
{
int i, s;
if(start > end){
return 0;
}
if(start == end){
return num[start];
}
if(f[start][end]){
return f[start][end];
}
for(i = 1; i <= end - start + 1; i++){
if(i == 1){
s = dp(start + i, end) + num[start];
}else{
s = dp(start + i, end) + abs(num[start] - num[start + i - 1]) * i;
}
f[start][end] = max(f[start][end], s);
if(i == 1){
s = dp(start, end - i) + num[end];
}else{
s = dp(start, end - i) + abs(num[end] - num[end - i + 1]) * i;
}
f[start][end] = max(f[start][end], s);
}
return f[start][end];
}
int main(int argc, char **argv)
{
int i;
int n;
scanf("%d", &n);
for(i = 0; i < n; i++){
scanf("%d", &num[i]);
}
printf("%d\n", dp(0, n - 1));
return 0;
}
浙公网安备 33010602011771号