dp

codeforces 1221

对着背影说爱祢 提交于 2019-11-30 04:30:35
传送门 A 2048 题意:multiset里面有许多2的幂,每次可以从multiset取出两个一样的数字,放回去两数之和,问能否出现2048. 分析:优先队列模拟操作 B knights 题意:棋子可以走日字,将n*n的棋盘用W与B填满,代表两个阵营的棋子,使得可以互相攻击的点对数量最大。 分析:大水题   解法一:   bfs,在左上角先放一个棋子,然后在可以攻击到的地方放敌对棋子,然后重复直到没有格子可以填。   解法二:   棋子与他可以攻击到的位置的曼哈顿距离为奇数,所以构造棋盘使得不存在相邻的B与W即可,就像国际象棋的棋盘。 C Perfect Team 题意:c,m,x代表coder,mathematician,和咸鱼,一只队伍必须要有一个coder和mathematician,必须要有三个人,求最多队伍数。 分析:解法一:不考虑人数配置,队伍数为(c+m+x)/3,考虑人数配置,将这个值跟c和m三个值取最小值即为答案。 解法二:比较容易想到,先组出c,m,x各一个的队伍,对于剩下来的人,二分可以组出的队伍数量,加上前面的结果就是答案。 D Make The Fence Great Again 题意:给定数组a和b,ai是第i元素的值,bi是将ai+1的代价,求最小代价,使得a中没有相邻的元素相同。 分析:首先,很容易想到对于每一个元素只需要+0,+1或

BZOJ3037 创世纪(基环树DP)

拜拜、爱过 提交于 2019-11-30 04:22:28
基环树DP,攻的当受的儿子,f表选,g表不选。并查集维护攻受关系。若有环则记录,DP受的后把它当祖宗,再DP攻的。 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a)) #define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a)) #define Fill(a,b) memset(a, b, sizeof(a)) #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b)) #define ll long long #define u32 unsigned int #define u64 unsigned long long #define ON_DEBUGG #ifdef ON_DEBUGG #define D_e_Line printf("\n----------\n") #define D_e(x) cout << (#x) << " : " << x << endl #define Pause() system("pause")

2019ccpc与icpc网络赛总结

一个人想着一个人 提交于 2019-11-30 00:44:09
网络赛总结 ccpc一场网络赛,icpc的六场网络赛,接近一个月的时间,收获了不少东西。 这几场网络赛,我们队伍主要采取的策略是两个人做一道题,这样我们把低级错误降到了最低,这几次网络赛基本上wa的都是思路的错误。但我们队伍明显的是出题速度慢,中等思维题还好,但时快时慢,但高等思维题很容易被卡,甚至到做到最后也没出,比如徐州那场的M题我们与出线队伍就差一道这个M题。队伍的更大短板是dp,而且只能说是中等dp,就比如沈阳一道完全背包的一点点的变形我想了很久才绕过来(还漏了个题意wa了一发),上海的一个计数dp问题,也没能做出来。 自己的短板是在中级思维题和dp上,这几场比赛最满意的一道题就是徐州的一道回文自动机+树状数组题,中等思维题容易卡,不是卡题意就是卡思路,然后拉着队友一起卡,浪费了大量时间,导致后面的题根本没时间看。高级思维题更不用说了,经常抓不着头脑,但赛后一看却不怎么难。 以后把精力放在中级和高级思维题上,主要把20场多校的中高级思维题看看,把其中牵涉的重要的数据结构补一下。网上的比赛依然要打,锻炼能力,就一个月了,为了牌,冲冲冲! 来源: https://blog.csdn.net/sdz20172133/article/details/100981608

力扣刷题70.爬楼梯(java)

耗尽温柔 提交于 2019-11-29 21:51:22
题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数。 示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 示例 2: 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 4. 1 阶 + 1 阶 + 1 阶 5. 1 阶 + 2 阶 6. 2 阶 + 1 阶 题解 动态规划法: 第 i 阶可以由以下两种方法得到: 在第 (i−1) 阶后向上爬一阶。 在第(i−2) 阶后向上爬 2 阶。 所以到达第 i 阶的方法总数就是到第(i−1) 阶和第 (i−2) 阶的方法数之和。 令 dp[i]dp[i] 表示能到达第 ii 阶的方法总数: dp[i]=dp[i−1]+dp[i−2] class Solution { public int climbStairs ( int n ) { if ( n == 1 ) { return 1 ; } int [ ] dp = new int [ n + 1 ] ; dp [ 1 ] = 1 ; dp [ 2 ] = 2 ; for ( int i = 3 ; i <= n ; i ++ ) { dp [ i ] = dp [ i - 1 ] + dp [ i - 2 ] ; }

技能树上的dp问题

自古美人都是妖i 提交于 2019-11-29 11:08:53
Description 热爱电子娱乐的同学们对于技能树一定不陌生.就是说,要先学习低级的垃圾技能,特定 的几个垃圾技能学会了,才能学习更强的技能.比如说,要先学火球术和烈火墙,才能学习地狱 烈焰.科技树也是一样.要先研究出电力和内燃机,才能研究工业学.那么,现在我们把问题简化, 这是一个技能树(或者科技树).格子上的数,是威力值.要先学会第一排第二个和第三个,才能 学会第二排的第二个.每个技能学习的前提都是左上和右上的两个技能.假设现在有一个第一 层有N 个技能的技能树,而且技能点是有限的,只能学习M 个技能,我们想知道最大的威力值 之和是多少. (ps:这个不是样例) Input Format 第一行两个数N 和M,如题所述 之后N 行,第i 行,有n+1-i 个数.表示一个技能树. Output Format 输出一个数,表示最大威力值之和 Sample Input 4 5 1 1 1 1 1 2 1 1 1 1 Sample Output 6 Data Limit 对于40%的数据,N<=10 对于100%的数据,N<=50,M<=500,所有数据都在int 之内. 技能树上的dp是一种不容易想到的dp问题,因为这种树状结构的dp大家都很熟悉,拿到这道题很容易就想成了树规或者从上向下,从下向上之类的dp问题,但是看到这道题的数据范围又是这么小,一看就有问题,然后就卡住了

Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)

*爱你&永不变心* 提交于 2019-11-29 08:32:49
Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组。 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,……。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。 给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。 示例 1: 输入: [1, 5, 2] 输出: False 解释: 一开始,玩家1可以从1和2中进行选择。 如果他选择2(或者1),那么玩家2可以从1(或者2)和5中进行选择。如果玩家2选择了5,那么玩家1则只剩下1(或者2)可选。 所以,玩家1的最终分数为 1 + 2 = 3,而玩家2为 5。 因此,玩家1永远不会成为赢家,返回 False。 示例 2: 输入: [1, 5, 233, 7] 输出: True 解释: 玩家1一开始选择1。然后玩家2必须从5和7中进行选择。无论玩家2选择了哪个,玩家1都可以选择233。 最终,玩家1(234分)比玩家2(12分)获得更多的分数,所以返回 True,表示玩家1可以成为赢家。 注意: 1 <= 给定的数组长度 <= 20. 数组里所有分数都为非负数且不会大于10000000。

Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game)

天大地大妈咪最大 提交于 2019-11-29 07:31:30
Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game) 亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] 。 游戏以谁手中的石子最多来决出胜负。石子的总数是奇数,所以没有平局。 亚历克斯和李轮流进行,亚历克斯先开始。 每回合,玩家从行的开始或结束处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止,此时手中石子最多的玩家获胜。 假设亚历克斯和李都发挥出最佳水平,当亚历克斯赢得比赛时返回 true ,当李赢得比赛时返回 false 。 示例: 输入:[5,3,4,5] 输出:true 解释: 亚历克斯先开始,只能拿前 5 颗或后 5 颗石子 。 假设他取了前 5 颗,这一行就变成了 [3,4,5] 。 如果李拿走前 3 颗,那么剩下的是 [4,5],亚历克斯拿走后 5 颗赢得 10 分。 如果李拿走后 5 颗,那么剩下的是 [3,4],亚历克斯拿走后 4 颗赢得 9 分。 这表明,取前 5 颗石子对亚历克斯来说是一个胜利的举动,所以我们返回 true 。 提示: 2 <= piles.length <= 500 piles.length 是偶数。 1 <= piles[i] <= 500 sum(piles) 是奇数。 数学题,但我们用DP来求解这一题。 我们首先定义一个类,名为P: private

BZOJ 4316: 小C的独立集

只谈情不闲聊 提交于 2019-11-29 06:32:21
4316: 小C的独立集 思路:先将树上的转移做好。然后环上的转移就是强制最上面的的点选或者不选,然后在环上跑一遍转移就可以了。 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr

Cow Exhibition

杀马特。学长 韩版系。学妹 提交于 2019-11-29 05:50:07
http://poj.org/problem?id=2184 Cow Exhibition #include<iostream> #include<string.h> #include<algorithm> using namespace std; #define maxn 105 int dp[200005]; int s[maxn]; int f[maxn]; int N; /* 思路:想要s和f之和都大于0,并且两者相加结果最大 那么可以利用dp[i]的下标记录i当前有多少smartness,dp[i]的值记录在当前smartness的限制下能获得的最大funness值 为了规避数组不能用负数来访问(有必要的,假如之前smartness负的很厉害,但是funness也很高,这时候出现一个samrtness超高同时funness一般般的往负数方向靠,那不就可以获得获得最优值的可能了吗) 需要将下界提高到100000,因为N最多100,单体smartness值最低-1000. 之后从100000的位置来寻求最优解就行了 Ps:注意此时dp值应该大于0并且要减去下界100000 最优解判断:if(j-100000+dp[j]>ans) ans=j-100000+dp[j]; 所以做一只既幽默又聪明的奶牛吧! */ /* But! ----------------

雷神领域(并查集真是个好东西)并查集+流氓dp

醉酒当歌 提交于 2019-11-29 04:46:47
考场上,整整看了半个小时以上的题目!!! 化简题意 : 给定一个全0矩阵,一些坐标点(x,y)为1,当三个点可以构成一个直角三角形时(直角边长为整数)拓展为一个矩形,之后从(0,0)出发,求最多的占用行数或占用列数 反正就是很麻烦的题就对了。。。 考场历程: 1、没看懂题,就去看下一题了 2、第三题可做性极差(tpsort+dp或网络流) 3、n^2拓展完了新点,发现样例就是个弟弟!(拓展完变成全1矩阵) 4、最小最大,想着二分来着,但是秒pass 5、想强行建边,跑最短路 6、dp根本想不出来....(行和列) 7、考完之后发现这题就是在侮辱智商 solution: 首先,n^2拓展点很容易,枚举点如何暴力即可。 先来讲dp怎么写吧..... 这个dp就是流氓..... 怎么说呢,考场上一直在想:跑一个行最优,列最优,比最小值,就成了最长不下降子序列之类的东西... 但是路径不一定是一个嘢.... 于是考场就暴毙了 其实,dp方程式.... 二维,f[i][j]表示从(0,0)拓展到当前点的最大值 如果当前点是1点,+1 如果不是,就更新,从左边和上边找一个最大值续上 我管你是行最大还是列最大,都给我最大然后+1再说 这就是这个dp欠的地方(还是我太弱了) dp的事解决了,加上之前的n^2拓展点,理论上5000*5000应该是能过去的,但是25000000,加上3~4的常数