Cunning Gena CodeForces - 417D
先将小伙伴按需要的监视器数量排序。然后ans[i][j]表示前i个小伙伴完成j集合内题目所需最少钱。那么按顺序枚举小伙伴,用ans[i-1][j]更新ans[i][j]和ans[i][j | 第i个小伙伴能完成题目的集合](更新后一种时答案要加上第i个小伙伴的费用)。
由于小伙伴已经按监视器数量排序了,对于每个枚举出的小伙伴i,可以试着将其作为最后一个要求助的小伙伴,那么此时监视器上花的钱就是这个小伙伴所需监视器数量*每个的费用,求助小伙伴费用就是ans[i][所有题目的集合],此时总费用就是这两者的总和。最终答案就是最小的枚举得到的总费用。
可以开滚动数组优化空间。
错误记录:45-47无效代码导致TLE
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 typedef long long LL; 7 LL n,m1,b; 8 struct A 9 { 10 LL x,k,v; 11 bool operator<(const A& b) const 12 { 13 return k<b.k; 14 } 15 }aa[110]; 16 LL ans[2][1048600]; 17 LL anss; 18 int main() 19 { 20 LL i,j,k,t,tt,ii=0; 21 scanf("%I64d%I64d%I64d",&n,&m1,&b); 22 for(i=1;i<=n;i++) 23 { 24 scanf("%I64d%I64d%I64d",&aa[i].x,&aa[i].k,&tt); 25 for(j=1;j<=tt;j++) 26 { 27 scanf("%I64d",&t); 28 //v[i].push_back(t); 29 aa[i].v|=(1<<(t-1)); 30 } 31 } 32 sort(aa+1,aa+n+1); 33 anss=0x3f3f3f3f3f3f3f3f; 34 memset(ans,0x3f,sizeof(ans)); 35 ans[0][0]=0; 36 for(i=0;i<n;i++) 37 { 38 ii^=1; 39 memset(ans[ii],0x3f,sizeof(ans[ii])); 40 for(j=0;j<(1<<m1);j++) 41 { 42 ans[ii][j]=min(ans[ii][j],ans[ii^1][j]); 43 ans[ii][j|aa[i+1].v]=min(ans[ii][j|aa[i+1].v],ans[ii^1][j]+aa[i+1].x); 44 } 45 /*for(j=0;j<(1<<m1);j++) 46 for(k=0;k<m1;k++) 47 ans[ii][j]=min(ans[ii][j],ans[ii][j|(1<<k)]);*/ 48 anss=min(anss,ans[ii][(1<<m1)-1]+b*aa[i+1].k); 49 } 50 if(anss!=0x3f3f3f3f3f3f3f3f) 51 printf("%I64d",anss); 52 else 53 printf("-1"); 54 return 0; 55 }