HDU 1074 Doing Homework
好难想到... ... 状态压缩DP,写的较搓
#include<cstdio> #include<cstring> #include<cmath> #include<stack> #include<vector> #include<string> #include<iostream> #include<algorithm> using namespace std; const int maxn=15; string CMP[40000]; struct X { string name; int d,c; } s[maxn]; int n,T,State; int dp[40000],add[40000]; int BaseA[20],totA; int BaseB[20],totB; stack<int>S; void ToA(int x) { totA=0; memset(BaseA,0,sizeof BaseA); while(x) { BaseA[totA++]=x%2; x=x/2; } } void ToB(int x) { totB=0; memset(BaseB,0,sizeof BaseB); while(x) { BaseB[totB++]=x%2; x=x/2; } } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); State=(1<<n)-1; for(int i=0; i<n; i++) { cin>>s[i].name; scanf("%d%d",&s[i].d,&s[i].c); } for(int i=0;i<=39000;i++) dp[i]=0x7fffffff,add[i]=-1,CMP[i].clear(); dp[0]=0; for(int i=1;i<=State;i++) { ToA(i); for(int j=0;j<n;j++) { if(BaseA[j]) { int preState=i-(int)pow(2.0,j); ToB(preState); int cost1=0; for(int k=0;k<totB;k++) if(BaseB[k]) cost1=cost1+s[k].c; cost1=cost1+s[j].c; int C; if(cost1<s[j].d) C=dp[preState]; else C=dp[preState]+cost1-s[j].d; if(C<dp[i]) { dp[i]=C,add[i]=j; char sign=j+'a'; CMP[i]=CMP[preState]+sign; } //保证字典序 else if(C==dp[i]) { char sign=j+'a'; string r=CMP[preState]+sign; if(r<CMP[i]) { add[i]=j; CMP[i]=r; } } } } } printf("%d\n",dp[State]); while(!S.empty()) S.pop(); int nowState=State; while(1) { S.push(add[nowState]); nowState=nowState-(int)pow(2.0,add[nowState]); if(nowState==0) break; } while(!S.empty()) { cout<<s[S.top()].name<<endl; S.pop(); } } return 0; }