递归超时的代码:
// Problem#: 1176 // Submission#: 2918390 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include <cstdio> #include <iostream> #include <cstring> #include <string> #include <queue> using namespace std; int A[1005]; int search(int l,int r) { int maxn,temp; if (r-l==1) return A[l]>=A[r]?A[l]:A[r]; if (A[l+1]>=A[r]) maxn=search(l+2,r)+A[l]; else maxn=search(l+1,r-1)+A[l]; if (A[l]>=A[r-1]) { temp=search(l+1,r-1)+A[r]; return maxn>temp?maxn:temp; } else { temp=search(l,r-2)+A[r]; return maxn>temp?maxn:temp; } } int main() { int n,i; int counter=0; while (1) { counter++; scanf("%d",&n); if (!n) break; int total=0; for (i=0;i<n;i++) { scanf("%d",&A[i]); total+=A[i]; } printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*search(0,n-1)-total); } }
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <queue> using namespace std; int A[1005]; int dp[1005][1005]; int search(int l,int r) { if (dp[l][r]) return dp[l][r]; int maxn,temp; if (r-l==1) return dp[l][r]=A[l]>=A[r]?A[l]:A[r]; if (A[l+1]>=A[r]) maxn=search(l+2,r)+A[l]; else maxn=search(l+1,r-1)+A[l]; if (A[l]>=A[r-1]) { temp=search(l+1,r-1)+A[r]; maxn=maxn>temp?maxn:temp; } else { temp=search(l,r-2)+A[r]; maxn=maxn>temp?maxn:temp; } return dp[l][r]=maxn; } int main() { int n,i; int counter=0; while (1) { counter++; memset(dp,0,sizeof(dp)); scanf("%d",&n); if (!n) break; int total=0; for (i=0;i<n;i++) { scanf("%d",&A[i]); total+=A[i]; } printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*search(0,n-1)-total); } }
动态规划的写法:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <queue> using namespace std; int A[1005]; int dp[1005][1005]; int main() { int n,i,j; int counter=0; while (1) { counter++; memset(dp,0,sizeof(dp)); scanf("%d",&n); if (!n) break; int total=0; for (i=0;i<n;i++) { scanf("%d",&A[i]); total+=A[i]; } for (i=0;i<n-1;i++) dp[i][i+1]=A[i]>A[i+1]?A[i]:A[i+1]; int l,r,maxn; for (i=3;i<n;i+=2) for (j=0;j+i<n;j++) { l=j; r=j+i; if (A[l+1]>=A[r]) maxn=A[l]+dp[l+2][r]; else maxn=A[l]+dp[l+1][r-1]; if (A[l]>=A[r-1]) maxn=maxn>(A[r]+dp[l+1][r-1])?maxn:(A[r]+dp[l+1][r-1]); else maxn=maxn>(A[r]+dp[l][r-2])?maxn:(A[r]+dp[l][r-2]); dp[l][r]=maxn; } printf("In game %d, the greedy strategy might lose by as many as %d points.\n",counter,2*dp[0][n-1]-total); } }