采用dp算法,记忆化搜索。
// edit by Colin
// 2014-10-27
// 硬币问题,1~N个面值,整数vi~vn,两个人玩游戏,一人一次只能从头或尾部取出一个。
// 假设两人都采用最优策略,求第一个人最后所的最大硬币和
#include <iostream>
#define MAXN 100
using namespace std;
// 表示i-j的和
int sum[MAXN][MAXN];
// 表示i-j的,一个人取的最优和
int f[MAXN][MAXN];
int main()
{
int i,j,len;
int a[8] = {4,2,45,2,11,22,53,89};
len = 4;
// 初始化
memset(f,-1,sizeof(f));
memset(sum,0,sizeof(sum));
for(i=0;i<len;++i){
f[i][i] = a[i];
sum[i][i] = a[i];
for(j=i+1;j<len;++j){
sum[i][j] = sum[i][j-1] + a[j];
}
}
for(i=0;i<len;++i){
for(j=0;j<len;++j)
cout<<sum[i][j]<<" ";
cout<<endl;
}
// dp算法
int deta;
for(deta = 1;deta< len;++deta){
for(i=0;i<len;++i)
{
j = i + deta;
if(j >= len)
break;
int num1 = sum[i][j] - f[i][j-1];
int num2 = sum[i][j] - f[i+1][j];
f[i][j] = num1>num2?num1:num2;
if(i == 0 && j == len-1)
cout<<num1<<" "<<num2<<endl;
}
}
cout<<f[0][len-1]<<endl;
return 0;
}