bzoj3824[Usaco2014 Dec]Guard Mark 奶牛叠罗汉(II)

题目链接: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;
}


posted @ 2016-10-17 10:18  OxQ  阅读(455)  评论(0编辑  收藏  举报