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)复杂度, ...
随机推荐
- MYSQL 定时自动执行EVENT
MySQL从5.1开始支持EVENT功能,类似Oracle和MSSQL的定时任务job功能.有了这个功能之后我们就可以让MySQL自动的执行存储过程来实现数据汇总等功能了,不用像以前哪样手动操作完成了 ...
- 【WPF】SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考
原文:[WPF]SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考 MSDN上解释了一大堆,二者对比来看,并不能发现什么明显的区别,微软爸爸也不知道多 ...
- 简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录
原文:简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录 在很多的时候,我们会在数据库的表中设置一个字段:ID,这个ID是一个IDENTITY,也就是说这是一个自增ID.当并发 ...
- 安卓ImageButton圆角按钮设置
首先图片要做成圆角的,使用美图秀秀,这个不多说. 之后使用设置了圆角的按钮,效果有缺陷,按钮会有灰色的边角. 类似这样: 去掉的方法是将layout的 android:src="@draw ...
- Windows 10 UWP 部署
原文 http://youthlin.com/20151105.html 我们知道VS连接手机可以直接部署到手机里,但平板貌似无法这样干,平板与电脑连接没有丝毫反应……那么想看VS里写的uwp应 ...
- Android多线程(一)
在Android应用的开发过程中,我们不可避免的要使用多线程,获取服务器数据.下载网络数据.遍历文件目录查找特定文件等等耗时的工作都离不开线程的知识.Android继承了Java的多线程体系,同时又实 ...
- C# ACCESS 向含有自动编码字段表中添加记录提示“查询值的数目与目标字段中的数目不同”
引发错误的SQL语句如下: sqlStr = "insert into tb_ReportLog values('" + DevSite + "','" + D ...
- Scintilla开源库使用指南
http://www.cnblogs.com/superanyi/archive/2011/04/07/2008636.html http://download.csdn.net/detail/den ...
- 全部的Windows消息对应值
以下是全部的Windows消息, 对于未在MSDN上的消息的WPARAM, LPARAM参数解释正确的给分 [已知 :0x0313, 0x01e2, 0x01e5, 0x01e ...
- linux下编译qt5.6.0静态库(使用./configure --help来看看都有哪些参数。超详细,有每一个模块的说明。如果改变了安装的目录,需要到安装目录下的bin目录下创建文件qt.conf)(乌合之众)good
linux下编译qt5.6.0静态库 linux下编译qt5.6.0静态库 configure生成makefile 安装选项 Configure选项 第三方库: 附加选项: QNX/Blackberr ...