您的位置:首页 > 其它

Educational Codeforces Round 21 E - Selling Souvenirs(三分or贪心背包)

2017-05-26 17:15 381 查看

题目链接:Educational Codeforces Round 21 E - Selling Souvenirs

题意:

有n个物品,每个物品有一个重量和价值,现在有一个m大的背包,问你最大能装多少价值。

题解:

做法一:

这题是加强版的01背包,不过有个特别的地方就是w只有三种。

所以可以枚举其中一种重量,然后三分查找。

因为剩下两种重量的函数值是一个单峰函数(不会证明)。

注意:在三分整数的时候,当区间只包含3个点时,有一个点访问不到,要手动补。

1 #include<bits/stdc++.h>
2 #define F(i,a,b) for(int i=a;i<=b;i++)
3 using namespace std;
4 typedef long long ll;
5 typedef pair<int,int> P;
6 const int N=1e5+7;
7
8 ll ans,dp
;
9 int ed,n,m;
10 struct node
11 {
12     int w,c;
13     double val;
14     node(int a=0,int b=0):w(a),c(b){}
15     bool operator<(const node &b)const{return val>b.val;}
16 }a
,tmp
;
17
18 ll DP()
19 {
20     F(i,1,ed)for(int j=m;j>=tmp[i].w;j--)
21         dp[j]=max(dp[j],dp[j-tmp[i].w]+tmp[i].c);
22     return dp[m];
23 }
24
25 int main()
26 {
27
28     scanf("%d%d",&n,&m);ans=0;
29     F(i,1,n)scanf("%d%d",&a[i].w,&a[i].c),a[i].val=1.0*a[i].c/a[i].w;
30     sort(a+1,a+1+n);
31     int tp[4];
32     memset(tp,-1,sizeof(tp));
33     F(i,1,n)
34     {
35         if(m<30)
36         {
37             ed=0;
38             while(i<=n)tmp[++ed]=a[i],i++;
39             F(ii,1,3)if(~tp[ii])tmp[++ed]=node(ii,tp[ii]),m+=ii,ans-=tp[ii];
40             ans+=DP();
41             break;
42         }
43         ans+=a[i].c;
44         m-=a[i].w;
45         tp[a[i].w]=a[i].c;
46     }
47     printf("%lld\n",ans);
48     return 0;
49 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: