#include<stdio.h> #include<iostream> #include<cmath> using namespace std; int map[1000][1000]; int num[1000]; const int oo=9000000; void dp(int n) { for(int i=0;i<n;i++) map[i][i]=num[i]; for(int i=0;i<n-1;i++) map[i][i+1]=int(abs(int(num[i]-num[i+1]))); for(int l=3;l<=n;l++){ for(int i=0;i<=n-l;i++){ int j=i+l-1; int max1,max2; if(num[i+1]>=num[j]) max1=num[i]-num[i+1]+map[i+2][j]; else max1=num[i] -num[j]+map[i+1][j-1]; if(num[i]>=num[j-1]) max2=num[j]-num[i]+map[i+1][j-1]; else max2=num[j]-num[j-1]+map[i][j-2]; map[i][j]=max(max1,max2); } } } int main() { int n; int count=0; while(scanf("%d",&n)) { if(!n) break; count++; for(int i=0;i<n;i++) for(int j=0;j<n;j++) map[i][j]=oo; for(int i=0;i<n;i++) scanf("%d",num+i); dp(n); printf("In game %d, the greedy strategy might lose by as many as %d points./n",count,map[0][n-1]); } }两种动态规划解决:自顶向下 和 自底向上 #include<stdio.h> #include<iostream> #include<cmath> using namespace std; int map[1001][1001]; int num[1001]; const int oo=9000000; int dp(int i,int j) { if(i+1==j) { int tmp=num[i]-num[j]; if(tmp<0) tmp*=(-1); return tmp; } if(map[i][j]!=oo) return map[i][j]; else{ int tmp1,tmp2; if(num[i+1]>=num[j]) tmp1=num[i]-num[i+1]+dp(i+2,j); else tmp1=num[i]-num[j]+dp(i+1,j-1); if(num[i]>=num[j-1]) tmp2=num[j]-num[i]+dp(i+1,j-1); else tmp2=num[j]-num[j-1]+dp(i,j-2); map[i][j]=max(tmp1,tmp2); } return map[i][j]; } int main() { int n; int count=0; while(scanf("%d",&n)) { if(!n) break; count++; for(int i=0;i<n;i++) for(int j=0;j<n;j++) map[i][j]=oo; for(int i=0;i<n;i++) scanf("%d",num+i); printf("In game %d, the greedy strategy might lose by as many as %d points./n",count,dp(0,n-1)); } }