您的位置:首页 > 其它

hdu 3182(状压dp)

2017-10-25 22:36 411 查看
传送门

题解:

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

调了一晚上。。。

只有复杂度允许,能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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  状压dp