http://codeforces.com/contest/808/problem/E

题意:给定n个重量为可能1,2,3的纪念品和各自的价值,问在背包总重量不超过m的条件下总价值最大为多少。

其中1 ≤ n ≤ 100000, 1 ≤ m ≤ 300000

首先可以想到的是重量相同的情况下,优先选择价值大的纪念品。所以我们可以把价值为1,2,3的纪念品分开,分别排序。

我们可以枚举重量为3的纪念品的个数为x,然后剩下的重量m-sum{3-elements}由1和2混合得出,这里可以动态规划预处理。

dp[i]是一个三元组{cost,cnt1,cnt2},分别表示重量为i的情况下的最大价值,以及这时候1和2分别用了多少。

dp[i]可以dp[i-1]和dp[i-2]推出。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<utility>
using namespace std;
typedef long long ll;
const int maxn=3e5+; struct node
{
ll cost;
int cnt1;
int cnt2;
}dp[maxn];
ll sum[maxn];
ll a[maxn],b[maxn],c[maxn];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
int weight;
ll cost;
int p=,q=,r=;
for(int i=;i<n;i++)
{
// scanf("%d%lld",&weight,&cost);
cin>>weight>>cost;
if(weight==)
{
a[p++]=cost;
}
else if(weight==)
{
b[q++]=cost;
}
else
{
c[r++]=cost;
}
}
sort(a,a+p);
sort(b,b+q);
sort(c,c+r);
dp[].cost=;
dp[].cnt1=p;
dp[].cnt2=q;
dp[].cost=a[p-];
dp[].cnt1=p-;
dp[].cnt2=q;
for(int i=;i<=m;i++)
{
if(dp[i-].cnt1->=&&dp[i-].cnt2->=)
{
if(dp[i-].cost+a[dp[i-].cnt1-]>dp[i-].cost+b[dp[i-].cnt2-])
{
dp[i].cost=dp[i-].cost+a[dp[i-].cnt1-];
dp[i].cnt1=dp[i-].cnt1-;
dp[i].cnt2=dp[i-].cnt2;
}
else
{
dp[i].cost=dp[i-].cost+b[dp[i-].cnt2-];
dp[i].cnt1=dp[i-].cnt1;
dp[i].cnt2=dp[i-].cnt2-;
}
}
else if(dp[i-].cnt1-<&&dp[i-].cnt2->=)
{
dp[i].cost=dp[i-].cost+b[dp[i-].cnt2-];
dp[i].cnt1=dp[i-].cnt1;
dp[i].cnt2=dp[i-].cnt2-;
}
else if(dp[i-].cnt1->=&&dp[i-].cnt2-<)
{
dp[i].cost=dp[i-].cost+a[dp[i-].cnt1-];
dp[i].cnt1=dp[i-].cnt1-;
dp[i].cnt2=dp[i-].cnt2;
}
else
{
break;
}
}
sum[r]=;
for(int i=r-;i>=;i--)
{
sum[i]=sum[i+]+c[i];
}
ll ans=;
for(int i=;i<=m;i++)
{
int x=(m-i)/;
ll temp=dp[i].cost+sum[max(r-x,)];
if(temp>ans)
{
ans=temp;
}
}
cout<<ans<<endl; return ;
}

注意一些小细节:

 ll temp=dp[i].cost+sum[max(r-x,)];

重量为3的可能不够用

【dp】E. Selling Souvenirs的更多相关文章

  1. Kattis - honey【DP】

    Kattis - honey[DP] 题意 有一只蜜蜂,在它的蜂房当中,蜂房是正六边形的,然后它要出去,但是它只能走N步,第N步的时候要回到起点,给出N, 求方案总数 思路 用DP 因为N == 14 ...

  2. HDOJ 1423 Greatest Common Increasing Subsequence 【DP】【最长公共上升子序列】

    HDOJ 1423 Greatest Common Increasing Subsequence [DP][最长公共上升子序列] Time Limit: 2000/1000 MS (Java/Othe ...

  3. HDOJ 1501 Zipper 【DP】【DFS+剪枝】

    HDOJ 1501 Zipper [DP][DFS+剪枝] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...

  4. HDOJ 1257 最少拦截系统 【DP】

    HDOJ 1257 最少拦截系统 [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...

  5. HDOJ 1159 Common Subsequence【DP】

    HDOJ 1159 Common Subsequence[DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...

  6. HDOJ_1087_Super Jumping! Jumping! Jumping! 【DP】

    HDOJ_1087_Super Jumping! Jumping! Jumping! [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...

  7. POJ_2533 Longest Ordered Subsequence【DP】【最长上升子序列】

    POJ_2533 Longest Ordered Subsequence[DP][最长递增子序列] Longest Ordered Subsequence Time Limit: 2000MS Mem ...

  8. HackerRank - common-child【DP】

    HackerRank - common-child[DP] 题意 给出两串长度相等的字符串,找出他们的最长公共子序列e 思路 字符串版的LCS AC代码 #include <iostream&g ...

  9. LeetCode:零钱兑换【322】【DP】

    LeetCode:零钱兑换[322][DP] 题目描述 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成 ...

随机推荐

  1. Json和序列化总结

    一.序言 遇到问题,就经常逛园,不知你是否曾有,曾经遇到的问题,或者在园子里看到问题的方案,过一段时间,有可能还会摔跤,哈哈...大神请勿喷,小弟记忆不太好,还过来找资料,如果自己写把问题或某个知识点 ...

  2. 微信小程序 开放能力学习

    1. 用户信息小程序登录使用微信的个人信息快速搭建用户体系,登录逻辑:小程序向微信获取code 给服务端生成用户. 说明1. 小程序端调用 wx.login() 获取临时登录凭证 code,并传到服务 ...

  3. 【学习笔记】HTML position(static、fixed、relative、absolute)

    [本文转载] position的四个属性值:static.fixed.relative.absolute 下面分别讲述这四个属性:<div id="parent">   ...

  4. netcdf源码在windows上的编译

    作者:朱金灿 来源:http://blog.csdn.net/clever101 今天搞搞netcdf源码在windows上的编译,折腾了半天,算是搞成了,特地记录一下过程.我的目标是要生成netcd ...

  5. php中include_path配置

    在php.ini中可配置include_path来达到在任何文件中都可以直接引入该目录下文件 include_path = ".:/usr/share/php:/var/www/phpxwl ...

  6. IOS代码收集

    http://mobile.51cto.com/hot-410417.htm 退回输入键盘: - (BOOL) textFieldShouldReturn:(id)textField{ [textFi ...

  7. Oracle EXPDP and IMPDP

    一.特点 • 可通过 DBMS_DATAPUMP 调用 • 可提供以下工具: – expdp – impdp – 基于 Web 的界面 • 提供四种数据移动方法: – 数据文件复制 – 直接路径 – ...

  8. 看云&gitbook 写帮助文档 | 专注于文档在线创作、协作和托管

    看云 写帮助文档 | 专注于文档在线创作.协作和托管 https://www.kancloud.cn/manual/thinkphp/1678 https://www.gitbook.com/

  9. python基础一 day2

    内容:   3%%s   输出:3%s       后面的全部转义 结果: 如果是因为执行break语句导致循环提前结束,就不会执行else. 单位换算: 编码方式: ascii  unicode u ...

  10. mybatis 实现批量更新

    更新单条记录 1 UPDATE course SET name = 'course1' WHERE id = 'id1'; 更新多条记录的同一个字段为同一个值 1 UPDATE course SET  ...