洛谷 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;
}

猜你喜欢

转载自www.cnblogs.com/Narh/p/9388403.html