从没写过状态dp,只是据说这是而已……
其实就是记录个当前点下可以达到的最大值,只有最大值更新后才向下级更新,过程就和spfa求最短路一样……
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #define INF 1E9 using namespace std; struct node { char s[101]; int C,D,E; }; node a[16]; int Min[70000]; int last[70000]; int ok; int n,t; void dfs(int time,int now,int ans) { if(now>=n)return; for(int i=0;i<n;i++) { int m=1<<i; if(ok&m)continue; ok|=m; t=time+a[i].E; if(t<0)t=0; if(ans+t<Min[ok])//记忆最大状态 { Min[ok]=ans+t; last[ok]=ok&(~m); dfs(time+a[i].C,now+1,ans+t);//继续搜索 } ok&=~m; } return; } void out(int t)//反向打印 { if(t==0)return; int tt=last[t],i; out(tt); t^=tt; for(i=0;i<n;i++) { if(t&1)break; t>>=1; } puts(a[i].s); } int main() { int T,i; scanf("%d",&T); while(T--) { ok=0; memset(Min,127,sizeof(Min)); scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s%d%d",a[i].s,&a[i].D,&a[i].C); a[i].E=a[i].C-a[i].D; } dfs(0,0,0); t=(1<<n)-1; printf("%d\n",Min[t]); out(t); } }