题目地址: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!的更多相关文章

  1. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  2. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  3. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  4. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  5. Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)

    题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...

  6. Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)

    题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...

  7. 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 ...

  8. Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)

    题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...

  9. Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (简单dp)

    题目:https://codeforces.com/problemset/problem/977/F 题意:一个序列,求最长单调递增子序列,但是有一个要求是中间差值都是1 思路:dp,O(n)复杂度, ...

随机推荐

  1. android studio中使用9-patch报错mergeDebugResource及Duplicate resources错误处理

    由于项目中新导入了两张图片,进行9-patch之后,文件名称包含XXXX.9.png , 而android studio 对资源文件的名称有要求仅支持[A-Z][a-z][0-9]格式  而XXX.9 ...

  2. 从PRISM开始学WPF(番外)共享上下文 RegionContext?

    原文:从PRISM开始学WPF(番外)共享上下文 RegionContext? RegionContext共享上下文 There are a lot of scenarios where you mi ...

  3. HTTP协议入门(一)- 版本

    当我们在浏览器的地址栏输入URL后,信息会被发送到WEB服务器,服务器得到响应,将数据传输回来,展示到WEB页面上,这其中的传输方法就是HTTP协议. 一.HTTP 0.9 发布于1991年,是首个H ...

  4. ubuntu 16.04 安装 openjdk 1.7

    由于编译Android源码需要openjdk1.7.X版本.ubuntu 16.04自带openjdk为1.8.X版本. sudo apt-get install openjdk-7-jre 或者su ...

  5. storm(二)消息的可靠处理

    storm 通过 trident保证了对消息提供不同的级别.beast effort,at least once, exactly once. 一个tuple 从spout流出,可能会导致大量的tup ...

  6. Tensorflow中循环神经网络及其Wrappers

    tf.nn.rnn_cell.LSTMCell 又名:tf.nn.rnn_cell.BasicLSTMCell.tf.contrib.rnn.LSTMCell 参见: tf.nn.rnn_cell.L ...

  7. Mac App Store应用签名和pkg签名,查看签名

    App签名 只有用苹果颁发的证书签名的应用才能在App Store上进行销售,所以我们开发的应用必须打上签名. 签名有两种方式,一是使用Xcode,在配置里面设置签名,编译出来的app就有了签名:二是 ...

  8. QT5的post Event解析

    大家都知道,QT的事件机制,查了好多网上的帖子,分析的不够到位,今天给大家分享下,我的分析,请高手指正:都知道post Event通过    QScopedPointer<QEvent> ...

  9. GO :互联网时代的 C 语言!

    摘要: 每周为您推送最有价值的开源技术内参! 技术干货 标签:独家译文 1.Go 很好,为什么我们不使用它? 在这篇文章中,我将分享一下为什么我认为它很棒,使用它的一些缺点,以及为什么它还不是我们 Z ...

  10. GetParent、SetParent、MoveWindow - 获取、指定父窗口和移动窗口,IsChild - 判断两个窗口是不是父子关系

    提示: SetParent 应该 Windows.SetParent, 因为 TForm 的父类有同名方法. //声明: {获取父窗口句柄} GetParent(hWnd: HWND): HWND; ...