http://acm.uestc.edu.cn/problem.php?pid=1489&cid=164

其实就是用搜索做0/1背包
不要被Fibonacci 唬住了,没什么用。,。。。。。这个比较坑爹
剪枝在代码中说明了

?View Code C
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 
#include "StdAfx.h"
#include <iostream>
#include <stdio.h>
#include  <memory.h>
#include <string>
#include <queue>
#include <math.h>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define LL long long
LL n,w,maxx;
LL f[60],ww[60];
LL m[51][51];
struct node
{
	LL c,w; 
};
node a[60];
bool cmp(node a,node b)
{
	if (a.w!=b.w) return a.w>b.w;
	else return a.c>b.c;
}
 
void find(int i,LL w,LL c,int flag)
{	
	if (c>maxx) maxx=c;
	if (i>=n) return ;
	//后面全选都没用
	if (f[n-1]-f[i]+a[i].c+c<=maxx) return;
	//后面全选都不会超重
	if (f[n-1]-f[i]+a[i].c+c>=maxx && ww[n-1]-ww[i]+a[i].w<=w)
	{
		maxx=f[n-1]-f[i]+a[i].c+c;
		return ;
	}
	if (flag==0 && a[i].w==a[i-1].w)             //上一个和a[i]等重而且价值更高的都没选,肯定不会选a[i]
	{
			//不选
			find(i+1,w,c,0);
			return ;
	}else
	{
	//不选
	find(i+1,w,c,0);
	//选
	if (w<a[i].w) return ;                        //超重了
	find(i+1,w-a[i].w,c+a[i].c,1); 
	}
 
}
 
int main()
{
 
	int t;
	cin>>t;
	for (int tt=0;tt<t;tt++)
	{
		cin>>n>>w;
		memset(a,0,sizeof(a));
		memset(m,0,sizeof(m));
		memset(f,0,sizeof(f));
		memset(ww,0,sizeof(ww));
		for (int i=0;i<n;i++)
		{
			cin>>a[i].w>>a[i].c;
		}
		maxx=0;
		sort(a,a+n,cmp);
		f[0]=a[0].c;
		ww[0]=a[0].w;
		for (int i=1;i<n;i++)
		{
			f[i]=f[i-1]+a[i].c;
			ww[i]=ww[i-1]+a[i].w;
		}
		find(0,w,0,1);
		cout<<"Case "<<tt+1<<": "<<maxx<<endl;
	}
 
 
	return 0;
}