您的位置:首页 > 其它

bzoj2621[Usaco2012 Mar]Cows in a Skyscraper 状压dp

2017-05-29 15:31 337 查看
。。比较基础的状压dp,可以拿来练手,有背包的性质。

设f[i]表示状态为i时的最小答案,g[i]表示状态为i是当前这个电梯剩下的最大空间。

那么我们枚举每一头牛看看超不超过当前空间,超过就不装或者新开一个电梯,最后输出满状态时的f就可以了。

具体细节看代码。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define inf 0x7f7f7f7f
using namespace std;
const int N=5e5+5;
int n,m;
int f
,g
;
int w
;
int cnt,k,mx;
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,n)scanf("%d",&w[i]);
mx=(1<<n)-1;
fo(i,0,mx)f[i]=inf,g[i]=m;
f[0]=0;
fo(i,0,mx-1)
{
fo(j,1,n)
if (!(i&(1<<j-1)))
{
int ftmp,gtmp;
if (g[i]>=w[j])
{
gtmp=g[i]-w[j];
ftmp=f[i];
}
else gtmp=m-w[j],ftmp=f[i]+1;
if (ftmp<f[i|(1<<j-1)])
{
f[i|(1<<j-1)]=ftmp;
g[i|(1<<j-1)]=gtmp;
}
else if (ftmp==f[i|(1<<j-1)])
g[i|(1<<j-1)]=max(g[i|(1<<j-1)],gtmp);
}
}
if (g[mx]!=m)f[mx]++;
printf("%d\n",f[mx]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: