11.05T1 大步贪心,小步DP

6056 -- 【模拟试题】完全背包

Description

  Maxtir有一个容量为m的背包。Sao有n种物品,第i种物品的体积为ai,价值为bi。Sao的每种物品都有无限多件,Maxtir可以任取。在不超过背包容量的前提下,Maxtir要求所能获得的最大价值。

Input

  第1行输入两个正整数n,m。
  第2至行n+1,每行输入两个正整数ai,bi。

Output

  输出仅一个整数,表示Maxtir所能获得的最大价值。

Sample Input

【输入样例#1】 2 15 3 2 5 3 【输出样例#1】 10 【输入样例#2】 3 70 71 100 69 1 1 2 140

Sample Output

 

Hint

【数据范围】
  对于20%的数据n,m<=10^3。
  对于40%的数据n,m<=10^4,ai,bi<=10。
  对于60%的数据n,m<=10^5。
  对于100%的数据n<=10^6,m<=10^16,ai,bi<=100。
 
 
 
 
此题我没有开long long爆炸
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<map>
 5 #define N 1000005
 6 using namespace std;
 7 struct node{
 8     long long a,b;
 9 }e[N];
10 long long f[N];
11 bool cmp(const node &a,const node &b){
12     return a.b*1.0/a.a*1.0>b.b*1.0/b.a*1.0;
13 }
14 long long gcd(long long a,long long b){
15     if(a<b)swap(a,b);
16     while(a=a%b)swap(a,b);
17     return b;
18 }
19 map<pair<long long,long long>,long long>check;
20 long long tot;
21 long long read(){
22     long long x=0,f=1;
23     char c=getchar();
24     while(!isdigit(c)){
25         if(c=='-')f=-1;
26         c=getchar();
27     }
28     while(isdigit(c)){
29         x=(x<<3)+(x<<1)+c-'0';
30         c=getchar();
31     }
32     return x*f;
33 }
34 int main(){
35     freopen("backpack.in","r",stdin);
36     freopen("backpack.out","w",stdout);
37     long long n,m;
38     n=read(),m=read();
39     for(long long i=1;i<=n;i++){
40         long long x,y;
41         x=read(),y=read();
42         if(check[make_pair(x,y)])continue;
43         check[make_pair(x,y)]=1;
44         e[++tot].a=x,e[tot].b=y;
45     }
46     n=tot;
47     sort(e+1,e+n+1,cmp);
48     long long max0=0;
49     for(long long i=1;i<=n;i++){
50         for(long long j=i+1;j<=n;j++){
51             max0=max(max0,e[i].a*e[j].a/(e[i].a,e[j].a));
52         }
53     }
54     long long VAL=0;
55     VAL+=(m-max0)/e[1].a*e[1].b;
56     m=max0+(m-max0)%e[1].a;
57     for(long long i=1;i<=n;i++){
58         for(long long j=e[i].a;j<=m;j++){
59             f[j]=max(f[j],f[j-e[i].a]+e[i].b);
60         }
61     }
62     cout<<VAL+f[m];
63     return 0;
64 }

over

转载于:https://www.cnblogs.com/saionjisekai/p/9911830.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值