Headmaster's Headache
UVA-10817
Ans [I] [s1] [s2] indicates that when considering the previous I, the set of subjects taught by at least one person is s1, minimum wage when the set of subjects taught by at least two persons is s2
The set is represented by a number. After being converted to binary, the I-bit status (1/0) starting from the end indicates the status of the I-th subject (meeting/not meeting certain conditions)
St [I] indicates the set of courses that I can teach, and cost [I] indicates the salary of I.
Ans [I] [s1 '] [s2'] = min (ans [I-1] [s1 '] [s2'], ans [I-1] [s1] [s2] + cost [I])
S1 '= s1 | st [I]
S2 '= s2 | (s1 & st [I])
Compress one dimension:
Apparently, s1 '> = s1, s2'> = s2
Therefore, ans [s1 '] [s2'] = min (ans [s1 '] [s2'], ans [s1] [s2] + cost [I]) s1 and s2 from large to small
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 char tt[500]; 6 int s,m,n,ans1,sa,sb; 7 int ans[1<<8][1<<8]; 8 int st[110],cost[110]; 9 int main()10 {11 int i,t,point,maxj,j,j1;12 scanf("%d%d%d",&s,&m,&n);13 while(s!=0)14 {15 memset(ans,0x3f,sizeof(ans));16 memset(st,0,sizeof(st));17 cin.getline(tt,500);18 ans1=0;19 sa=0;sb=0;20 for(i=1;i<=m;i++)21 {22 //memset(tt,'\0',sizeof(tt));23 cin.getline(tt,500);24 point=0;25 sscanf(tt,"%d",&t);26 ans1+=t;27 while(tt[point]<='9'&&tt[point]>='0') ++point;28 while(tt[point]==' ') ++point;29 while(point<strlen(tt))30 {31 sscanf(tt+point,"%d",&t);32 t=1<<(t-1);33 sb|=sa&t;34 sa|=t;35 while(tt[point]<='9'&&tt[point]>='0') ++point;36 while(tt[point]==' ') ++point;37 }38 }39 ans[sa][sb]=ans1;40 for(i=1;i<=n;i++)41 {42 //memset(tt,'\0',sizeof(tt));43 cin.getline(tt,500);44 point=0;45 sscanf(tt,"%d",&cost[i]);46 while(tt[point]<='9'&&tt[point]>='0') ++point;47 while(tt[point]==' ') ++point;48 while(point<strlen(tt))49 {50 sscanf(tt+point,"%d",&t);51 st[i]|=1<<(t-1);52 while(tt[point]<='9'&&tt[point]>='0') ++point;53 while(tt[point]==' ') ++point;54 }55 }56 maxj=(1<<s)-1;57 for(i=1;i<=n;i++)58 for(j=maxj;j>=0;j--)59 for(j1=maxj;j1>=0;j1--)60 {61 sa=j|st[i];62 sb=j1|(j&st[i]);63 ans[sa][sb]=min(ans[sa][sb],ans[j][j1]+cost[i]);64 }65 printf("%d\n",ans[maxj][maxj]);66 scanf("%d%d%d",&s,&m,&n);67 }68 return 0;69 }