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; }