hdu 3182(状压dp)

传送门

题解:

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

调了一晚上。。。

只有复杂度允许,能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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值