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;
}
posted @ 2011-07-15 16:58  zqynux  阅读(253)  评论(0编辑  收藏  举报