题意:两个原子碰撞会消失一个原子,同时产生大量的能量。问你这些原子碰撞后产生的最大能量。
状态很好设定,本来我是这样设定的dp[i][j],表示i状态时j消失,只要枚举和j碰撞的原子即可,后来发现其实那个i状态没用,就去掉了直接dp[i],刚开始觉得倒过来dp有点麻烦,就直接把题目反过来,就是一个原子分成两个,放出一定的能量,求最大,这样做就能顺着来dp了,后来写了一下反过来,也就多了几步。
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
2637634 | 2011-08-23 17:56:21 | Accepted | 3471 | C++ | 60 | 196 | xym |
#include<cstdio> #include<cstring> #include<string> #include<iostream> #include<cmath> #include<algorithm> using namespace std; int dp[1<<11],a[11][11],n; void DP() { memset(dp,0,sizeof(dp)); //反题意写 /*for(int i=0;i<(1<<n);i++) for(int j=0;j<n;j++) { if(!(i&(1<<j)))continue; int tem=i-(1<<j); for(int k=0;k<n;k++) { if(!(tem&(1<<k)))continue; dp[i]=max(dp[i],dp[tem]+a[k][j]); } } printf("%d\n",dp[(1<<n)-1]);*/ //顺题意写 for(int i=(1<<n)-1;i>0;i--) for(int j=0;j<n;j++) { if(!(i&(1<<j)))continue; for(int k=0;k<n;k++) { if(i&(1<<k)||j==k)continue; int tem=i+(1<<k); dp[i]=max(dp[i],dp[tem]+a[j][k]); } } int ans=-1; for(int i=0;i<n;i++) ans=max(ans,dp[1<<i]); printf("%d\n",ans); } int main() { while(1) { scanf("%d",&n); if(n==0)break; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { scanf("%d",&a[i][j]); } DP(); } }