题目链接:http://poj.org/problem?id=2923
题目大意:有两辆车和n个货物,每个货物有自己的重量,
车子有承载重量,问把货物全部拉走最少需要车子来回跑几趟;
思路:因为n<=10,所以可以状态压缩,总状态量为 1<<n,写个判断函数,把每种可以一次运走的状态储存,
然后就是DP,dp[j|state[i]]=min(dp[j|state[i]],dp[j]+1);
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<math.h>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const double pi=acos(-1.0);
const ll mod=1e9+7;
const int N=1e3+30;
int dp[N];
int vis[N],w[12];
int e,a,b,n,state[N];
int judge(int x)//判断该状态是否符合条件
{
int sum=0;
memset(vis,0,sizeof(vis));
vis[0]=1;//能装下的重量标记为1
for(int i=0;i<n;i++)
{
if((x>>i)&1)
{
sum+=w[i];
for(int j=a;j>=w[i];j--)
{//这里可以模拟一下,列入a=7,w[1]=5,w[2]=3,w[3]=2,自行模拟
if(vis[j-w[i]])
vis[j]=1;
}
}
}
if(a+b<sum) return 0;
for(int i=0;i<=a;i++)
{//就算sum<a+b,也不一定满足条件,需要再判断
if(vis[i]&&sum-i<=b)
return 1;
}
return 0;
}
void init()
{
e=0;
for(int i=1;i<(1<<n);i++)
{
dp[i]=inf;//初始化
if(judge(i))
state[e++]=i;//可以一次运走的状态
}
}
int main()
{
int T,cas=0;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d",&n,&a,&b);
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
init();
dp[0]=0;
for(int i=0;i<e;i++)//dp找出最小花费
{
for(int j=(1<<n)-1;j>=0;j--)
{
if(dp[j]==inf) continue;
if((j&state[i])==0)
dp[j|state[i]]=min(dp[j|state[i]],dp[j]+1);
}
}
printf("Scenario #%d:\n%d\n\n",++cas,dp[(1<<n)-1]);
}
return 0;
}