题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3824
题目大意:
题解:
状压dp
f[i]表示已经选了i的奶牛来叠的最大安全因子为多少。
因为已经知道选了什么,所以高度是一定的(用了sm[i]来存)
对于每个sm[i]≥L,ans=max(ans,f[i])。选个最大值~
小吐槽:神tm一开始以为要用long long,然后I64d交bzoj交了好几次!显示WA!让我还以为USACO的数据水到了这种地步..改成int之后快了两秒!两秒啊!还能说什么!
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
// typedef long long LL;
#define maxn 1100000
#define N 30
const int inf = 1e9;
int f[maxn],sm[maxn];
int h[N],w[N],s[N];
int mymax(int x,int y){return (x>y)?x:y;}
int mymin(int x,int y){return (x<y)?x:y;}
int main()
{
//freopen("guard.in","r",stdin);
//freopen("guard.out","w",stdout);
int n,L,i,k,mx,sum=0,ans;
scanf("%d%d",&n,&L);
for (i=1;i<=n;i++)
{
scanf("%d%d%d",&h[i],&w[i],&s[i]);
sum+=h[i];
}mx=(1<<n)-1;sm[0]=0;f[0]=inf;
for (i=1;i<=mx;i++) f[i]=-1;
ans=-1;sm[mx]=sum;
for (i=0;i<=mx;i++)
{
for (k=1;k<=n;k++)
if (!(i&(1<<k-1)))
{
int xx=i|(1<<k-1);
if (w[k]>f[i]) continue;
f[xx]=mymax(f[xx],mymin(s[k],f[i]-w[k]));
sm[xx]=sm[i]+h[k];
}
if (sm[i]>=L && f[i]!=inf) ans=mymax(ans,f[i]);
}
if (ans==-1) printf("Mark is too tall\n");
else printf("%d\n",ans);
return 0;
}