A题: Yougth‘s Game[Ⅲ]( 区间dp )
这是在省赛前热身赛出的题目,可能是题目中有用到博弈的思想,很多人都在做,而且在尝试暴力。但是没有人往dp的方向上想。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 1200; int a[N],dp[N][N],n; int b[N]; int main() { while(~scanf("%d",&n)) { b[0]=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i]=b[i-1]+a[i]; } memset(dp,0,sizeof(dp)); for(int l=1;l<=n;l++) { for(int i=1,j=l;j<=n;i++,j++) { dp[i][j]=max(dp[i][j],a[i]+(b[j]-b[i]-dp[i+1][j])); dp[i][j]=max(dp[i][j],a[j]+(b[j-1]-b[i-1]-dp[i][j-1])); } } printf("%d\n",dp[1][n]-(b[n]-dp[1][n])); } return 0; }
#include<stdio.h> #include<string.h> #include <string> #include <iostream> using namespace std; const int N = 10008; int s[108],t; int sg[N]; bool hash[N]; void sg_solve(int *s,int t,int N) //N求解范围 S[]数组是可以每次取的值,t是s的长度。 { int i,j; memset(sg,0,sizeof(sg)); for(i=1;i<=N;i++) { memset(hash,0,sizeof(hash)); for(j=0;j<t;j++) if(i - s[j] >= 0) hash[sg[i-s[j]]] = 1; for(j=0;j<=N;j++) if(!hash[j]) break; sg[i] = j; } } int main() { int x,y; while(~scanf("%d%d",&x,&y)) { int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&s[i]); sg_solve(s,n,N); if(sg[x]^sg[y]^sg[x*y]==0) printf("Yougth is best\n"); else printf("No\n"); } return 0; }
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 12; int a[N][N],dp[1<<N]; int main() { int n; while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&a[i][j]); memset(dp,0,sizeof(dp)); for(int state=0; state<(1<<n); state++) { for(int i=0; i<n; i++) //枚举初始合并点 { if(state&(1<<i)) continue; for(int j=0; j<n; j++) //跟哪一个合并 { if((state&(1<<j))) continue; if(i==j) continue; int newstate=state+(1<<j); dp[newstate]=max(dp[newstate], dp[state]+a[i][j]); } } } int maxnum=0; for(int i=0; i<(1<<n); i++) maxnum=max(maxnum, dp[i]); printf("%d\n", maxnum); } return 0; }
原文:http://blog.csdn.net/y990041769/article/details/25195683