Codeforces Round #565 (Div. 3) F.Destroy it!
题目地址:http://codeforces.com/contest/1176/problem/F
思路:其实就是一个01背包问题,只是添加了回合和每回合的01限制,和每当已用牌数到了10的倍数,那张卡会触发double攻击。
因为卡使用的多少会触发double效果,所以我们要记录攻击的同时记录卡的使用次数,可以由01背包dp[N][N]改变,
第一个维度是当前是第几个回合,第二个维度是记录卡在用了n张的情况下造成的攻击力,但是dp[N][N](N <= 2e5),
占用内存太大显然不行。于是想到用dp[N][10]。
(因为卡的数量可能很多,我们其实只要记录最多三张1费,一张2费,一张3费)
每个回合用卡情况最多3种:
1.用3张一费卡。
2.用2张一费卡,或者1张一费卡,1张二费卡
3.用1张一费卡,或者1张二费卡,或者1张三费卡
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define mod(x) ((x)%(MOD)) typedef long long LL;
const int MOD = ;
const int N = 2e5 + ;
LL dp[N + ][]; void init(){
rep(i, , N) rep(j, , ) dp[i][j] = -;
} int main(){ ios::sync_with_stdio(false);
cin.tie(); init(); int n;
cin >> n; dp[][] = ;//初始化 rep(o, , n){
int num;
cin >> num; int L1 = ;
int L2 = ;
int L3 = ;
int c1[] = { };//费用1,记录v最大的三张
int c2 = ;//费用2
int c3 = ;//费用3 int c, v;
rep(i, , num){
cin >> c >> v; if (c == ){
if (L1 == ){
int x = ;
if (c1[x] > c1[]) x = ;
if (c1[x] > c1[]) x = ;
if (v > c1[x]) c1[x] = v;
}
else c1[++L1] = v;
}
else if (c == ){
L2 = ;
if (v > c2) c2 = v;
}
else if (c == ){
L3 = ;
if (v > c3) c3 = v;
}
} sort(c1 + , c1 + + ); int max_v = max(c1[], max(c2, c3));//一张v最大的
int _2_1 = c1[];//两张卡费用最大的
int _2_2 = c1[];
if (c2 > _2_2) _2_2 = c2;
if (_2_2 > _2_1) swap(_2_2, _2_1);//两张卡,由1费中间v最大的2张,和一张2费的中间选出v最大的两张
LL _3 = c1[] + c1[] + c1[];//用三张1费 rep(i, , ) dp[o][i] = dp[o - ][i];//先把上个回合的状态保存到当前回合,方便下边的比较
//因为这三种状态都是附加在上个状态下得出的,所以他们之间都是独立的。
//mod(i + x),(i + x >= 10)* value 用于判断是否满足大于等于用的次数是十张的倍数
rep(i, , ){
if (dp[o - ][i] != -){//上个状态是存在的
if (L1 + L2 + L3 >= ){//用的卡牌最少一张的时候,用一张情况 dp[o][mod(i + )] = max(dp[o][mod(i + )],
dp[o - ][i] + max_v + (i + >= )*max_v); }
if (L2 + L1 >= ){//1费2费用的卡牌至少有两张,用两张情况 dp[o][mod(i + )] = max(dp[o][mod(i + )],
dp[o - ][i] + _2_1 + _2_2 + (i + >= )*_2_1); }
if (L1 >= ){//1费卡牌数最少三张,用三张情况 dp[o][mod(i + )] = max(dp[o][mod(i + )],
dp[o - ][i] + _3 + (i + >= )*c1[]); }
}
}
} LL ans = -; //rep(i, 0, n){
// rep(o, 0, 9) cout << dp[i][o] << " ";
// cout << endl;
//}
//cout << endl; rep(o, , ) ans = max(dp[n][o], ans); cout << ans << endl; return ;
}
Codeforces Round #565 (Div. 3) F.Destroy it!的更多相关文章
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- Codeforces Round #501 (Div. 3) F. Bracket Substring
题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)
题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...
- Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)
题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...
- Codeforces Round #325 (Div. 2) F. Lizard Era: Beginning meet in the mid
F. Lizard Era: Beginning Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...
- Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)
题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...
- Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (简单dp)
题目:https://codeforces.com/problemset/problem/977/F 题意:一个序列,求最长单调递增子序列,但是有一个要求是中间差值都是1 思路:dp,O(n)复杂度, ...
随机推荐
- CommandParameter binding Introduction:
Design Patterns SampleCode https://csharpdesignpatterns.codeplex.com/ DevExpress Support Center http ...
- 【图文教程】de4dot实战字符串解密(演示:hishop微分销系统)
原文:[图文教程]de4dot实战字符串解密(演示:hishop微分销系统) 前些日子,公司需求开发一个微分销系统,于是找来hishop微分销系统想借鉴一下,没想到里面各种加密,就连字符串也都加密了. ...
- Linux命令扫盲 之 sar
今天在读<大规模Web服务开发技术>一书的时候,书中提到了sar这个命令,感觉很有用,有必要整理学习一下.(对于一位Linux初学者,不能放过任何一个学习机会 :P) 打开自己的CentO ...
- 深入理解Delphi的消息机制(别人写的,简明扼要,用来复习)
永远记住,无论你是用 SDK 还是借用 VCL 来创建窗口,都要遵循 Windows 的游戏规则,即先注册窗口类,然后再创建窗口实例,在消息循环中写实现代码.你还要知道 Windows 已经为了我们预 ...
- Android零基础入门第79节:Intent 属性详解(上)
Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的各属性.本期将详细介绍Intent的各属性值,以及 Android如何根据不同属性值来启动相应的组件. ...
- Linux数据流的重定向
>覆盖内容:>>追加内容:<和>的区别在于重定向方向不一致,>表示重定向从左到右:>>和<<类似 简单的重定向 0 /dev/stdin 标 ...
- Screensiz.es站收集整理了移动端的相关尺寸。
Screensiz.es站收集整理了移动端的相关尺寸. Screensiz.es 彩蛋爆料直击现场 Screensiz.es站收集整理了移动端的相关尺寸.
- Qt使用MinGW编译,如何忽略警告
Qt编译时经常出现以下警告: warning: unused parameter 'arg1' [-Wunused-parameter] warning: unused variable 'i' [- ...
- NPOI 超简单的导出导入
首先说说,第一次遇到过匿名导出的那个时候是在我在北京第一家公司,简单的声明一个对象就可以导出,那时候感觉高大上,自己也想研究研究,但是因为头将代码后来加密了根本看不到.好吧,研究了研究放弃了,后来 ...
- Kafka笔记5
Kafka使用zookeeper来维护集群成员的信息.每个broker都有一个唯一标识符,这个标识符可以在配置文件指定,也可以自动生成. 在broker停机,出现网络分区或者长时间垃圾回收停顿时,br ...