动态规划
文章平均质量分 60
BACKUP_zw
github: github.com/zhewang95
blog: zhewang95.github.io
展开
-
蓝桥杯基础训练 ALGO-122 未名湖边的烦恼
题目上标的是递推,确实要用递推做,当然,如果数据规模够小的话可以直接用公式,组合数学大法好啊#include#include#define MAX 20using namespace std;long long dp[MAX][MAX];long long fun(long long a){ if(a==0) return 1LL; return fun(a-1)*a;原创 2016-03-04 20:34:40 · 975 阅读 · 0 评论 -
UVA - 10604 Chemical Reaction
本身记忆化搜索没什么难的,但被自己坑了几次。首先是dfs里面少了恢复minus[i]的语句,当时根本没意识到这里的错误,结果debug了半天才找到。然后是注意处理只有一个管子的情况,这时的热量应该是0.最坑的就是i与j反应和j与i反应结果可能会不同,看了stainger的题解才知道#include#include#include#include#define MAXN 7原创 2015-05-20 12:04:44 · 959 阅读 · 0 评论 -
UVA - 11258 String Partition
开始没仔细考虑,看成了区间dp,这样复杂度会到十的七次方,果断超时,后来才发现,可以直接线性dp,从前向后do即可#include#include#include#include#define MAX 210#define BOD 2147483647using namespace std;char s[MAX];long long len,dp[MAX];void in原创 2015-04-28 16:57:09 · 330 阅读 · 0 评论 -
UVA - 10911 Forming Quiz Teams
简单记忆化搜索,用二进制位表示组队情况#include#include#include#include#include#define MAX 8#define INF 10000000using namespace std;int n,vis[1<<(2*MAX)],cases=1;char name[MAX*2][25];double x[MAX*2],y[MAX*2]原创 2015-04-28 12:34:29 · 278 阅读 · 0 评论 -
UVA - 10626 Buying Coke
记忆化搜索,有几个地方要特别注意,首先a最大不止500,因为通过其他硬币可以找出额外的一快硬币。然后注意可能有效并且数量最小的硬币种类组合,开始我只想到了四种,这四种无论再多加任何一种硬币都不会获得更好的结果,但一直wa,后来才发现其实a=2,c=1也是一种需要考虑的情况,因为这样售货机一定会找一个五块的,状态发生了有效的转移。考虑问题一定要周到啊#include#include#incl原创 2015-04-17 18:35:03 · 442 阅读 · 0 评论 -
UVA - 10564 Paths through the Hourglass
简单的dp,特殊的地方稍加处理下就行了,很多考编程能力的细节要注意。注意结果可能很大,要用long long ,另外vim用着还是可以的#include#include#include#include#include#define MAXN 25#define MAXM 510using namespace std;int n,s,ss[MAXN*2][MAXN];long原创 2015-04-09 23:09:59 · 261 阅读 · 0 评论 -
UVA - 662 Fast Food
怎么说呢,我一直希望自己能独立的想出从没见过的类型的题目,但基本上从来没有过,究竟是自己不够聪明还是说这就是变聪明的过程??但除了第二个答案我别无选择。。。首先要想清楚一段restruant只有取中间的那个才有可能取得最小值,以这个为基础,(当然,一开始实在想不通怎么状态转移),dp[i][j]表示前i个取j个的最小值,如果直接n*k复杂度遍历,显然无法得到解,就只好再枚举最后一段的长度,这样原创 2015-04-15 21:52:51 · 327 阅读 · 0 评论 -
UVA - 11151 Longest Palindrome
经典的回文串区间dp注意没说串不包含空格就很有可能会有空格#include#include#include#include#define MAX 1010using namespace std;char s[MAX];int dp[MAX][MAX];void init(){ for(int i=0;i<MAX;i++){ for(int j=0原创 2015-04-08 18:35:27 · 316 阅读 · 0 评论 -
UVA - 10635 Prince and Princess
好题,一道题目复习了多个知识点首先一看就是lcs,可以用n*n的dp来做,但一看数据量,n可以到10000,虽然空间可以优化,但绝对要超时。于是就只能先把lcs 转化成lis再用nlgn的算法求出来。首先,将lcs转化成lis:将s1中的数字在s2中出现的位置记下来并由大到小排列,然后用排列后的数组替换s1中该数字出现的所有位置,这题各个数字都是不同的,所以做着非常方便,注意如果数字重原创 2015-04-08 20:19:22 · 324 阅读 · 0 评论 -
UVA - 10401 Injured Queen Problem
作为dp题并不难,关键是注意写法。不需要先判断是否与前一行和后一行冲突,因为最后相加的时候冲突的是被排除出去的。#include#include#include#include#define MAX 20using namespace std;char s[MAX],board[MAX][MAX];long long dp[MAX][MAX];int main(){原创 2015-04-08 12:08:47 · 288 阅读 · 0 评论 -
UVA - 10891 Game of Sum
开始我想的是代码一那种方法,但总感觉正确性证明不够严密,看了下别人的思路,才写了代码二。实际上状态转移还是比较简单的,由于每个人都采取最优的策略,也就是从最“长远”处考虑,所以从较小情况向较大情况递推是能够得出整体最优解的。代码一之所以错误,是因为人为地限制了每种情况取最优解的方向,实际上不是正确的全局最优解。代码一:#include#include#include#include原创 2015-04-14 16:32:23 · 331 阅读 · 0 评论 -
scu2222: Health Power
乍一看很像背包但不好背,因为score可以无限而且要先补满hp,也就是和加入背包的顺序有关。由于所有food的score总量是一定的,于是问题可以转化成获得至少k的hp的情况下尽量少的使用score,注意只要hp大于等于k都可以,所以状态转移时要把大于等于k的都纳入k下,否则背包上界也不好处理#include#include#include#define MAXK 1010#defin原创 2015-04-07 19:24:55 · 431 阅读 · 0 评论 -
UVA - 10313 Pay the Price
初看以为是简单的dp,结果发现直接dp的结果有重复,也就是错误的把不同顺序考虑了进去,所以要用三维,第一维是面值为i的钱,并且是完全背包。需要注意的是由于dp的初始值全为不合理情况-1,故在最后累加的时候要将-1视为0,这样的错误对我来说还是比较隐蔽的,还是要提高编程能力#include#include#include#define MAX 350#define INF 10000原创 2015-04-07 23:37:16 · 343 阅读 · 0 评论 -
UVA - 10453 Make Palindrome
区间dp,加上方案打印在方案打印这坑了很久,关键是找到一个清晰的算法而不是貌似可以的算法#include#include#include#include#define MAX 1100using namespace std;char s[MAX];int dp[MAX][MAX],len;void print_ans(int l,int r,int ans){原创 2015-03-31 22:42:36 · 250 阅读 · 0 评论 -
UVA - 10201 Adventures in Moving - Part IV
状态转移很明显遗憾只在poj上通过了。。。#include#include#includeusing namespace std;const int MAXN=110;int main(){ int distance,dp[MAXN][MAXN*2],T,stations,station[MAXN][2]; char input[30]; scanf(原创 2015-03-12 17:35:33 · 276 阅读 · 0 评论 -
poj1015Jury Compromise
完完全全用自己的思路做了一道dp题,感觉对dp的理解又加深了一层题目其实可以抽象为:从n个数对里面选出m个数对,使得所有数对的第一个数字之和与第二个数字之和的差尽量接近于0且所有数字之和尽量大。如果直接从两部分的差值最小来设计状态转移的话很困难,因为如果子问题的差值的绝对值最小,不一定总体的差值绝对值最小。考虑到题目的数据量不算太大,可以考虑通过每个差值的最大数字之和来设计状态转移,这样最原创 2015-03-29 10:45:50 · 345 阅读 · 0 评论 -
UVA - 10913 Walking on a Grid
简单dp。由于只能横着走和向下走以及每个格子只能走一次。可以枚举i,j 这个位置时,下一行应该在哪个位置核心部分冗余度很高,但想不出0冗余又不会增加复杂度的办法。。。干脆就直接把代码复制一边然后改个循环#include#include#include#include#define MAXN 76#define MAXK 6using namespace std;int n,k原创 2015-05-20 19:32:51 · 399 阅读 · 0 评论 -
UVA - 10118 Free Candies
做完觉得其实很简单,但当初最开始思考的时候却思路十分不畅,卡了很久,还是对问题的特点分析不够迅速有效。开始我一看,就觉得是记忆化搜索,但是想了想,如果从0,0,0,0这个状态开始的话,那下一个状态难道是这个状态的子状态?可这样就矛盾了,因为先取的才应该是子状态锕。在这里我卡了很久,虽然当时我已经想清楚对于一个a,b,c,d,的状态,得到的糖的数目是一定的,但我没有充分利用这个条件。那如果从n,原创 2015-05-18 16:18:09 · 369 阅读 · 0 评论 -
蓝桥 算法训练 ALGO-116 最大的算式
蓝桥题目的风格和acm差异很大啊,感觉acm需要的是纯粹的算法,蓝桥算法考的没有这么难但是对编程能力的要求也不低。所以做的时候感觉怪怪的这道题注意要用long long,然后5层循环要是放在acm里面应该是比较少见的吧#include#include#include#include#define MAX 20using namespace std;long long原创 2016-03-04 18:57:41 · 1203 阅读 · 0 评论 -
poj1837 balance 背包
注意这里每个砝码都要用上,所以状态转移时只转移上一个砝码用上的情况。由于这里要求的是种数,直接相加就可以了,所以加的值如果是0就代表上一个(或多个)砝码没有用上的情况对本状态没有贡献#include#include#include#include#define MAXN 25#define MAXM 16000#define MID 7550using namespace std原创 2016-01-13 16:40:59 · 334 阅读 · 0 评论 -
UVA 11552 Fewest Flops
水题#include#include#include#include#define MAX 1100using namespace std;char s[MAX];int L,k,dp[MAX][26],count_t[26];void init(){ cin>>k; cin>>s; L=strlen(s); memset(dp,0x7f,sizeof(dp));原创 2015-11-24 11:56:04 · 367 阅读 · 0 评论 -
UVA 1424 Salesmen
简单dp#include#include#include#include#define MAX 210using namespace std;int n,m,l,path[MAX],graph[MAX][MAX],dp[MAX][MAX];void init(){ cin>>n>>m; memset(graph,0,sizeof(graph)); int a,b; f原创 2015-11-23 22:16:55 · 303 阅读 · 0 评论 -
UVA 11584 Partitioning by Palindromes
受区间dp思路影响太严重。。。开始没用记忆化,tle了#include#include#include#include#define MAX 1010using namespace std;char s[MAX];int dp[MAX][MAX],L,dp1[MAX][MAX];void init(){ gets(s); L=strlen(s); memset(d原创 2015-11-23 19:54:47 · 306 阅读 · 0 评论 -
UVA - 10558 A Brief Gerrymander
恩,核心是01背包,结果,我托了三个月才ac....... 结果发现,是容斥定理用错了。。。这几天,我应该好好扇自己的脸。。。#include#include#include#include#define MAX 105using namespace std;int n,s,a,grid[MAX][MAX],sumgrid[MAX][MAX],sep[MAX];int dp[M原创 2015-10-24 19:34:38 · 340 阅读 · 0 评论 -
UVA - 10163 Storage Keepers
开始并没有注意到需要使两个量最优与只要求一个量最优有什么不同,就定义dp[i][j]为前i个人看守j个storage的最大安全线,然后顺便把wage求出来。交上去却一直wa。疑惑不解的去看别人的代码,郁闷的发现所有人都用了两次dp,我开始非常不解,既然薪水是由人决定的为什么还要再用一次dp?后来仔细想想才发现这样做的道理,从较高的抽象层面看,定义的状态dp[i][j]本身就是求一个量的最优值的,而原创 2015-07-23 19:04:08 · 251 阅读 · 0 评论 -
UVA - 10817 Headmaster's Headache
花了四个多小时做这道题,碰到这样不算难但自己解决不好的题才意识到自己各个方面的不足。开始,我自己能够想到要用状态压缩的背包来解决。课有些问题一直没搞清楚,因为每个老师能教的课程不一定非得他交,我就认为状态转移时还要考虑各门课教还是不交,然后初始化也是一样。这样就比较麻烦,最后我还是写出来了,但复杂度太高,TLE,然后才发现不一定非要考虑教还是不交,因为遍历的时候每种状态都会考虑,这样,只要初始原创 2015-07-23 15:40:01 · 364 阅读 · 0 评论 -
UVA - 10280 Old Wine Into New Bottles
首先觉得总容量很大,瓶子种类很多,直接完全背包肯定不行。但是既然数据大的离谱,肯定有别的方法可以降低复杂度。我的大致思路对了,就是找到完全背包的上界,但是在具体实现上碰到了一些问题,包括最后对复杂度还是没有自信。两个方面,一个是完全背包上界:maxx=min(maxx,s[i][0]*s[i][0]/(s[i][1]-s[i][0]));另一方面是粗算瓶子种类有180*100=18000种原创 2015-07-31 17:00:43 · 506 阅读 · 0 评论 -
UVA 10599 Robots(II)
开始没想出什么思路,看了题解恍然大悟,是LIS,不过一看数据量O(n*n)的复杂度要到十的八次方,就一直在思考nlgn,也就是加上二分的方法应该怎么做。可是思来想去觉得难以实现,后来才发现数据比较水,直接N的平方几十毫秒就过了#include#include#include#include#define MAX 105using namespace std;int l[M原创 2015-07-20 22:12:49 · 480 阅读 · 0 评论 -
UVA - 709 Formatting Text
我是这样状态转移的,一维dp[i]表示前i个字符的badness的最小值,且i为最后一行的最后一个字符,这样可以保证dp最后一定是最小值,但题目要求输出开始的badness最小的情况,光有状态转移是不能保证这个条件的,开始我想的是,使i所在的那行单词尽量少,这样前面的单词尽量多就可以在总体上保证前面的badness最小,但交上去wa,后来想了一下,这样只是总体最小,不一定前面的某个局部最小,于是状原创 2015-07-31 10:55:56 · 366 阅读 · 0 评论 -
UVA - 10723 Cyborg Genes
这道题应该说我没有完完全全的搞懂,仍然有点晕晕呼呼的感觉。对于s1[i]==s2[j]的情况,直接dp[i][j][t]=dp[i-1][j-1][t-1]就行了,因为s1[i]前面的字母必须在s1[i]之前,s2同理(感觉像是废话).所以只要在s1[i]前面和s2[j]前面的后面直接加上相同的字母就行了。对于s1[i]!=s2[j]的情况,就有两种情况,一种是s1[i]在前,一种是s2[原创 2015-06-12 16:37:15 · 288 阅读 · 0 评论 -
UVA - 11008 Antimatter Ray Clearcutting
状压dp,值得注意的地方还是很多的。开始时始终思路不畅,不太清楚究竟该怎么定义状态,所以搁置了很久。后来才明白,由于最后剩下的树的状态有很多种,而开始所有树还在的状态只有一种,所以可以把状态定义为,当前还剩这么些树的时候,要使剩下的树小于n-m棵至少需要的射线数,这样,开始所有树都在的情况就是最大的父状态。这里要注意总结,一般最特殊的状态总是作为最大的父状态。然后是状态压缩上一些编程技巧和原创 2015-06-10 21:05:37 · 438 阅读 · 0 评论 -
BestCoder Round #42
第一次打bc,也是我第一次打这种比赛,做出来三道不过system test时挂掉一道。原来比赛是这么的好玩。。。总的来说,还是有很多收获的首先我感觉,我的手速还是有了那么一点提升的A题水题代码略B题变形二分#include#include#include#include#define MAX 100010using namespace std;int n,m,shoo原创 2015-05-23 21:48:12 · 287 阅读 · 0 评论 -
UVA - 607 Scheduling Lectures
简单的dp#include#include#include#include#define MAX 1010using namespace std;int s[MAX],dp[MAX][MAX];int n,l,c,cases=1;void init(){ memset(dp,0x7f,sizeof(dp)); dp[0][0]=0;}int main(){ wh原创 2015-05-19 15:48:20 · 336 阅读 · 0 评论 -
UVA - 10154 Weights and Measures
开始怎么都想不通,过几天再想才明白过来。这道题还是让我收获很多的首先乌龟的叠放涉及到一个次序问题,如果用搜索显然会超时,但用dp的话很难把状态和顺序结合起来,这里就要先证明一个贪心选择性质:如果a比b的力量小且能够承载b,那么换成b承载a就会获得更好地总体效果。这里开始我想错了,认为应该优先把净承载力大的放在底下,这样所有上面的乌龟就可以获得一个更有力的基础,但实际上这里是不满足无后效性的,因原创 2015-03-11 19:08:06 · 260 阅读 · 0 评论 -
UVA - 11137 Ingenuous Cubrency
一开始竟然没看出来是完全背包。。navie!!!!dp[i]+=dp[i-v];#include#include#includeusing namespace std;const int MAX=10010;int s[23];long long dp[MAX];int main(){ for(int i=1;i<23;i++) s[i]=i*i*原创 2015-02-25 22:16:54 · 268 阅读 · 0 评论 -
UVA - 10617 Again Palindrome
区间dp其实就是统计从整个字符串中取出任意数量的字符使之成为palindrom,当s[i]==s[j]时,根据容斥原理,dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+dp[i+1][j-1]+1;其中,dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]是[i,j]区间内的长度不超过j-i的回文串,dp[i+1][j-1]是区间内的长度原创 2015-02-25 18:48:39 · 296 阅读 · 0 评论 -
UVA - 10285 Longest Run on a Snowboard
dp。。。开始我想的按高度排序,原创 2014-10-26 14:16:35 · 288 阅读 · 0 评论 -
UVA - 10130 SuperSale
就是01背包,每个人同一件物品原创 2014-10-26 09:25:35 · 313 阅读 · 0 评论 -
UVA - 348 Optimal Array Multiplication Sequence
dp矩阵链乘 不解释。最优子结构为最后一个乘号原创 2014-10-25 09:47:00 · 281 阅读 · 0 评论 -
UVA - 531 Compromise
LCS 不解释。。打印方案的地方没想清楚,花了点时间。。。原创 2014-10-26 11:06:28 · 280 阅读 · 0 评论