【dp】E. Selling Souvenirs
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的更多相关文章
- Kattis - honey【DP】
Kattis - honey[DP] 题意 有一只蜜蜂,在它的蜂房当中,蜂房是正六边形的,然后它要出去,但是它只能走N步,第N步的时候要回到起点,给出N, 求方案总数 思路 用DP 因为N == 14 ...
- HDOJ 1423 Greatest Common Increasing Subsequence 【DP】【最长公共上升子序列】
HDOJ 1423 Greatest Common Increasing Subsequence [DP][最长公共上升子序列] Time Limit: 2000/1000 MS (Java/Othe ...
- HDOJ 1501 Zipper 【DP】【DFS+剪枝】
HDOJ 1501 Zipper [DP][DFS+剪枝] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- HDOJ 1257 最少拦截系统 【DP】
HDOJ 1257 最少拦截系统 [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDOJ 1159 Common Subsequence【DP】
HDOJ 1159 Common Subsequence[DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDOJ_1087_Super Jumping! Jumping! Jumping! 【DP】
HDOJ_1087_Super Jumping! Jumping! Jumping! [DP] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- POJ_2533 Longest Ordered Subsequence【DP】【最长上升子序列】
POJ_2533 Longest Ordered Subsequence[DP][最长递增子序列] Longest Ordered Subsequence Time Limit: 2000MS Mem ...
- HackerRank - common-child【DP】
HackerRank - common-child[DP] 题意 给出两串长度相等的字符串,找出他们的最长公共子序列e 思路 字符串版的LCS AC代码 #include <iostream&g ...
- LeetCode:零钱兑换【322】【DP】
LeetCode:零钱兑换[322][DP] 题目描述 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成 ...
随机推荐
- SpringBoot 2.x (5):异常处理与部署WAR项目
异常处理: SpringBoot的异常处理是不友好的,前端只会显示最基本的错误名称 后端控制台会报出具体的错误,那么我们如何告知前端具体的错误信息呢? 1:对全局异常进行处理 一个测试的Control ...
- 自动创建xml文档
自动创建xml文档 import xml.etree.ElementTree as ET print(dir(ET)) #ET里面有Element方法 root = ET.Element(" ...
- chrome inspect出现白屏的解决方案
点inspect后 弹出框,可是里面一片白色 PS:原效果不是这样,只是图找不到随便p的 原因可以看这个:http://www.cnblogs.com/slmk/p/7591126.html 大概意思 ...
- IOS应用
下面是这个类的一些功能: 1.设置icon上的数字图标 //设置主界面icon上的数字图标,在2.0中引进, 缺省为0 [UIApplicationsharedApplication].applica ...
- Javascript中setTimeout()以及clearTimeout( )的使用
setTimeout setTimeout( ) 是属于 window 的 method, 这是用来设定一个时间,时间到了, 就会执行一个指定的 方法.练习一:等候三秒才执行的 alert( )set ...
- pocket API学习笔记
最近安装了pocket离线阅读软件. 为了收藏需要的URL,每次都要打开浏览器.然后按google工具条上的pocket+. 网页多的时候,这个过程就非常缓慢. 根据pocket网站的API介绍,我可 ...
- springboot设置接口超时
springboot 设置接口超时 1.配置文件 application.properties中加了,意思是设置超时时间为20000ms即20s, spring.mvc.async.request-t ...
- mongodb windows 开机启动
1)新建存放db E:\mongodb\data\db 2)新建日志文件 E:\mongodb\logs\log.txt 3)管理员运行Cmd 4)CD mongodb安装路径 5)运行命令 mong ...
- net core 使用ef生成实体类(SqlServer)
1)打开程序包管理器控制台 2)输入命令 Install-Package Microsoft.EntityFrameworkCore.SqlServer 3)输入命令 Install-Packag ...
- 如何使用postman访问网站
1.输入Request URL2.选择Request Method3.输入需要的Request Headers注意:一般token会在Headers中