hdu 1074 状压dp
题意:有n门课,每门课有截止时间和完成所需的时间,如果超过规定时间完成,每超过一天就会扣1分,问怎样安排做作业的顺序才能使得所扣的分最小
链接:点我
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN=16; 16 int n,m,tt; 17 int dp[1<<MAXN]; 18 int pre[1<<MAXN]; 19 struct node 20 { 21 int d,c; 22 char ss[100]; 23 }nn[MAXN]; 24 void printpath(int st) 25 { 26 if(st==0) return; 27 int flag=0; 28 for(int i=0;i<n;i++) 29 { 30 if( ((st&(1<<i))!=0)&&(pre[st]&(1<<i))==0) //之前有而现在没有,这里括号一定要括好,太坑爹了 31 { 32 flag=i; 33 break; 34 } 35 } 36 printpath(pre[st]); 37 printf("%s\n",nn[flag].ss); 38 } 39 int main() 40 { 41 int i,j,k; 42 #ifndef ONLINE_JUDGE 43 freopen("1.in","r",stdin); 44 #endif 45 scanf("%d",&tt); 46 while(tt--) 47 { 48 scanf("%d",&n); 49 for(i=0;i<n;i++) 50 { 51 scanf("%s%d%d",&nn[i].ss,&nn[i].d,&nn[i].c); 52 } 53 for(i=0;i<(1<<n);i++) dp[i]=INF; 54 dp[0]=0; 55 for(i=0;i<(1<<n);i++) 56 { 57 for(j=0;j<n;j++) 58 { 59 int s=0; 60 if(i&(1<<j)) continue; //已经做过了 61 for(k=0;k<n;k++) 62 { 63 if(i&(1<<k)) s+=nn[k].c; 64 } 65 s+=nn[j].c; 66 if(s>nn[j].d) s-=nn[j].d; 67 else s=0; 68 if(dp[i|(1<<j)]>dp[i]+s) 69 { 70 dp[i|(1<<j)]=dp[i]+s; 71 pre[i|(1<<j)]=i; 72 } 73 } 74 } 75 printf("%d\n",dp[(1<<n)-1]); 76 printpath((1<<n)-1); 77 } 78 return 0; 79 }