NKOJ P1628 岳麓山提水【迭代加深】【背包DP】

我们对选取的木桶种数进行限制(即枚举迭代加深中的层数),然后根据这个限制进行搜索我们选择哪些木桶,然后背包验证一下当前方案是否可行。

#include 
#include 
#include 
#include 
#include 
#define db double
#define sg string
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=2e5+5;
const ll Inf=1e18;

ll n,m,flag,v[N],f[N],ans[N];

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

void dp(ll num) {
	memset(f,0,sizeof(f));f[0]=1;
	
	rep(i,1,num) rep(j,ans[i],n) f[j]|=f[j-ans[i]];
	
	if(f[n]) {
		flag=1;printf("%lld ",num);
		rep(i,1,num) printf("%lld ",ans[i]);
	}
}

void dfs(ll cur,ll cnt,ll num) {
	if(flag) return ;
	
	if(cnt==num) {
		dp(num);return ;
	}
	
	rep(i,cur+1,m) {
		ans[cnt+1]=v[i];
		dfs(cur+1,cnt+1,num);
		if(flag) return ;
	}
}

int main() {
//	freopen("nkoj1628.txt","r",stdin);
	
	n=read(),m=read();
	
	rep(i,1,m) v[i]=read();
	
	sort(v+1,v+1+m);
	
	rep(i,1,m) {
		dfs(0,0,i);
		
		if(flag) return 0;
	}

	return 0;
}

你可能感兴趣的:(NKOJ,动态规划与递推,动态规划-背包DP,搜索-迭代加深)