题目:http://www.gdfzoj.com/oj/contest/270/problems/4
蒜头君酷爱搭积木,他用积木搭了 n 辆重量为 wi的小车和一艘最大载重量为 W 的小船,他想用这艘小船将 n 辆小车运输过河。每次小船运载的小车重量不能超过 W。另外,小船在运载小车时,每辆小车会对小船有一个损坏值 si,当多辆小车一起运载时,该趟运载对小船的损坏值为船上所有小车的最大损坏值。
现在蒜头君想知道,如何用小船运载 n 辆小车,可以使得对小船造成的总损坏值最小。
跟corn field很像
https://mp.youkuaiyun.com/postedit/82555831
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int W,n,num=0;
int w[16+5],C[16+5];//质量,损坏值
int f[1<<16],g[1<<16],c[1<<16];
void dfs(int s,int p,int wei,int sun)
{
if (p>n)
{
num++;
g[num]=s;
c[num]=sun;
return ;
}
if (wei+w[p]<=W)
{
if (sun==0)
dfs(s+(1<<(p-1)),p+1,wei+w[p],C[p]);
else
dfs(s+(1<<(p-1)),p+1,wei+w[p],max(C[p],sun));
}
dfs(s,p+1,wei,sun);
}
int main()
{
int i,s;
freopen("a.txt","r",stdin);
memset(w,0,sizeof(w));
memset(c,0,sizeof(c));
memset(f,0x3f,sizeof(f));
scanf("%d%d",&W,&n);
for (i=1;i<=n;i++)
scanf("%d%d",&C[i],&w[i]);
dfs(0,1,0,0);
f[0]=0;
for (s=0;s<(1<<n);s++)
{
for (i=1;i<=num;i++)
{
if ((s&g[i])>0)
continue;
f[s+g[i]]=min(f[s+g[i]],f[s]+c[i]);
}
}
printf("%d",f[s-1]);
return 0;
}