洛谷 3112 [USACO14DEC]后卫马克Guard Mark——状压dp
题目:https://www.luogu.org/problemnew/show/P3112
状压dp。发现只需要记录当前状态的牛中剩余承重最小的值。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=25,Lm=(1<<20)+5,INF=1e9+5; int n,lm,ht[N],wh[N],sg[N],f[Lm],ans=-1; ll h,dp[Lm]; int main() { scanf("%d%lld",&n,&h); lm=(1<<n); for(int i=1;i<=n;i++) scanf("%d%d%d",&ht[i],&wh[i],&sg[i]); f[0]=INF; for(int s=0;s<lm;s++) { for(int j=1;j<=n;j++) if((s&(1<<(j-1)))==0&&f[s]>=wh[j]) { int d=(s|(1<<(j-1))); f[d]=max(f[d],min(f[s]-wh[j],sg[j])); dp[d]=dp[s]+ht[j]; } if(dp[s]>=h)ans=max(ans,f[s]); } if(ans==-1)puts("Mark is too tall"); else printf("%lld\n",ans); return 0; }