蒜头军的积木

蒜头君酷爱搭积木,他用积木搭了 nn 辆重量为 w_iwi 的小车和一艘最大载重量为 WW 的小船,他想用这艘小船将 nn辆小车运输过河。每次小船运载的小车重量不能超过 WW。另外,小船在运载小车时,每辆小车会对小船有一个损坏值 s_isi,当多辆小车一起运载时,该趟运载对小船的损坏值为船上所有小车的最大损坏值。

现在蒜头君想知道,如何用小船运载 nn 辆小车,可以使得对小船造成的总损坏值最小。

输入格式

第一行输入两个数 WW 和 nn100\leq w\leq 400100w4001\leq n\leq 161n16),分别表示小船的最大载重量和小车总数。

接下来输入 nn 行,每行输入两个整数 s_isi 和 w_iwi1 \leq s_i \leq 501si5010 \leq w_i \leq 10010wi100),分别表示每辆小车对小船的损坏值和每辆小车的重量。

输出格式

输出一行,输出一个整数,表示用小船运载 nn 辆小车,最小的总损坏值。

样例输入

90 4
32 50
15 20
40 50
13 40

样例输出

72

解题说明:

ac代码:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
const int maxn=70000;
const int mxx=2000000000;
int cost[maxn];
int w,si[20],weight[20];
void doit(int x){
	int s1=0,w2=0;
	int cot=1;
	int temp=x; 
	while(x){
		if(x&1){
			s1=max(si[cot],s1);
			w2+=weight[cot];
			if(w2>w){
				cost[temp]=mxx;
				return;
			}
		}
		cot++;
		x>>=1;
	}
	cost[temp]=s1;
	return;
}
int main(){
	int n;cin>>w>>n;
	for(int i=1;i<=n;i++){
		cin>>si[i]>>weight[i];
	}
	for(int i=0;i<(1<<n);i++){
		  doit(i);
	}
	for(int i=0;i<(1<<n);i++){
		for(int j=i;j;j=(j-1)&i){
			cost[i]=min(cost[i],cost[j]+cost[j^i]);
		}
	}
	int dd=pow(2,n)-1;
	cout<<cost[dd]<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxk_hi/article/details/79994956
今日推荐