NKOJ P1628 嶽麓山提水【迭代加深】【揹包DP】
阿新 • • 發佈:2018-12-14
我們對選取的木桶種數進行限制(即列舉迭代加深中的層數),然後根據這個限制進行搜尋我們選擇哪些木桶,然後揹包驗證一下當前方案是否可行。
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #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; }