题目大意:01背包,但花费和价值都是10w 可是商品只有100个
题解:搜索01背包,对花费进行排序,记下前缀和,然后搜索时强剪枝就好了。
PS:这题改编自一个usaco的原题 http://blog.csdn.net/eod_realize/article/details/38656021
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define sint long long
sint w[1100],c,ans,sum[1100];
int n;
struct node
{
int c,w;
}sa[1100];
sint sc[1100],sw[1100];
void dfs(int order,sint left,sint get)
{
if(order==1)
{
if(left>=sa[1].c) ans=max(ans,get+sa[1].w);
else ans=max(ans,get);
return;
}
if(left>=sc[order])
{
ans=max(ans,get+sw[order]);
return;
}
if(get+sw[order]<=ans) return;
dfs(order-1,left,get);
if(left>=sa[order].c)
{
dfs(order-1,left-sa[order].c,get+sa[order].w);
}
}
bool cmp(node aa,node bb)
{
return aa.c<bb.c;
}
int main()
{
while(scanf("%d%d",&n,&c)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&sa[i].c,&sa[i].w);
}
sort(sa+1,sa+1+n,cmp);
for(int i=1;i<=n;i++)
{
sc[i]=sc[i-1]+sa[i].c;
sw[i]=sw[i-1]+sa[i].w;
}
if(sc[1]>c)
{
printf("0\n");
continue;
}
int i;
for(i=n;i>=1;i--)
{
if(c>=sa[i].c)break;
}
ans=0;
dfs(i,c,0);
printf("%lld\n",ans);
}
return 0;
}