OJ上DP的一些题目:
two ends:比较简单,将题分解,最后简化成只有最后两个数,符合DP特性。
#include<cstdio>
#include<iostream>
#include<cstring>
#define MAXN 1001
using namespace std;
int list[MAXN];
int result[MAXN][MAXN];
int sum;
int dp(int beg,int end)
{
int max = 0;
if(result[beg][end]==0) //还没有进行计算
{
if(beg+1==end){ //如果只剩下两个数,A一定要用贪婪
if(list[beg]>list[end])
max = list[beg];
else
max = list[end];
}
else{
// 运用DP,分解成子问题,A无非只有两种取法,取左和取右,分别贪心,进行比较,取大值
int leftNum = list[beg];
if(list[beg+1]>=list[end])
leftNum += dp(beg+2,end);
else
leftNum += dp(beg+1,end-1);
int rightNum = list[end];
if(list[beg]>=list[end-1])
rightNum += dp(beg+1,end-1);
else
rightNum += dp(beg,end-2);
if(leftNum >rightNum)
max = leftNum;
else max = rightNum;
}
result[beg][end]=max;
}
return result[beg][end];
}
int main()
{
int n;
int num =1;
cin>>n;
while(n>0)
{
memset(list,0,sizeof(list)) ;
memset(result,0,sizeof(result));
for(int i =0;i<n;i++){
scanf("%d",&list[i]);
sum+=list[i];
}
cout << "In game " << num++ << ", the greedy strategy might lose by as many as " << 2*dp(0,n-1)-sum << " points." << endl;
cin>>n;
}
return 0;
}