hdu 3182(状压dp)

来源:互联网 发布:文心雕龙数据库有吗 编辑:程序博客网 时间:2024/06/01 08:01

传送门

题解:

略,满足条件就转移,否则不转移,完了。

调了一晚上。。。

只有复杂度允许,能for的就for(比如dp时内层对n的循环),不要为了追求一点速度就去写什么lowbit来提取二进制的1,此可谓弄巧成拙敲打

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int n,m,v[16],c[16],pre[16];int dp[1<<16];inline int read() {int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();return x*f;}int main() {//freopen("hdu 3182.in","r",stdin);int kase=read();while (kase--) {memset(dp,0,sizeof(dp));memset(pre,0,sizeof(pre));n=read(),m=read();for (int i=0;i<n;++i) v[i]=read();for (int i=0;i<n;++i) c[i]=read();for (int i=0;i<n;++i) {int num=read();while (num--) {int x=read()-1;pre[i]|=(1<<x);}}for (int st=0;st<(1<<n);++st) {int tmp=st,cost=0;for (int p=0;p<n;++p)if (st&(1<<p)) cost+=c[p];if (cost>m||!dp[st]&&st) continue;for (int p=0;p<n;++p)if (!(st&(1<<p))&&(pre[p]&st)==pre[p]&&cost+c[p]<=m)dp[st|(1<<p)]=max(dp[st|(1<<p)],dp[st]+v[p]);}int ans=0;for (int st=0;st<(1<<n);++st) ans=max(ans,dp[st]);printf("%d\n",ans);}return 0;}


原创粉丝点击