摘要:给出几种硬币,数量不限,问你用着几种硬币能组成价值为n的种类是多少。第一眼看到,求数量,就想到dp,直接找转移方程dp[i] = dp[i] + dp[i - coin[j]];/* ID: xvoid191 PROG: money LANG: C++*/#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;long long coin[30],dp[10001];int n,v;int main(){ freop
阅读全文
文章分类 - 动态规划(DP)+贪心
摘要:题目意思给出一个整数数列,1到n,把它分为两组数,要求两组数的和相等。根据题目,首先可以判定当1到n 的和是4的倍数或者被4整除余1的话,才可以被拆分,否则直接breakn个数的总和为sum:=n*(n+1)shr 1,当且仅当sum为偶数的时候才有解,sum为奇数时直接输出0并且退出程序;但是这样做了也还是会超时。所以要进行优化处理。经计算 只有n=4K 和n=4K-1 (K属于正整数)时才有解 不然直接输零 也不用计算了。动态规划 设分成的子集为set1,set2,sum=(n*(n+1)div 2)div 2. 设f[i,j]表示取前i个数,使set1总数和为j的方案数.第i个数的值为i
阅读全文
摘要:dp的经典题目怎么那么多呢?我所谓的经典就是简单但是自己怎么就没有想到转移方程的题目啊啊啊!!这道题给出节点数n,还有数的层数k,问你能组成多少种二叉树要求是每个节点的孩子数只能是0或者2设dp[i,j]表示用i个点组成深度最多为j的二叉树的方法数,则:dp[i,j]=∑(dp[k,j-1]×dp[i-1-k,j-1])(k∈{1..i-2})边界条件:dp[1,i]=1我们要求的是深度恰好为K的方法数S,易知S=dp[n,k]-dp[n,k-1]。但需要注意的是,如果每次都取模,最后可能会有dp[n,k]<dp[n,k-1],所以可以用S=(dp[n,k]-dp[n,k-1]
阅读全文
摘要:V个村庄,选出P个点要求距离最短。想到dp方程,dp[i][j],表示前i个村庄中放置j个邮局所需的费用dp[i][j] = min(dp[i][j],dp[k][j-1] + sum[k+1][j]);sum表示i和j之间,放置一个邮局的话最小的费用,此时放到最中间为最小费用/*poj1060 邮局选址,动态规划*/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#define MAX 301using
阅读全文
摘要:一个工作流图,只有一个开始节点,多个结束点每个结点有个multi属性:true:表示其前驱节点必须都完成工作才可进行当前节点工作.false: 表示其前驱节点有一个完成工作即可进行当前节点工作。每个节点工作消耗1个工作单位,最终从开始节点,需要最少多少时间可以到任一结束点。乍一看我以为是网络流类的题目,想着怎么建图啊之类的,后来想下,可以逆向思考这道题。从结束点开始往前驱点推,如果当前点属性是true,就找前驱点里max的工作时间,如果为false,就找前驱点里min的最终用得到时间+1就是当前点的工作时间了,由于图是单向的,所以可以当作一棵树来考虑,就成了树形dp了。mintime数组,表示
阅读全文
摘要:很久就看推荐题目有这个了,一直没做,因为看了好几次没看懂,都说dp,这几天看了状态压缩后明白了,其实就是用二进制来表示各个位置的状态然后进行枚举,把状态放进数组里就行,在这里用dp[i][j][k]表示第i行,当前j状态,i-1行是k状态时候的最大炮数dp[i][j][k]=MAX(dp[i][j][k],dp[i-1][k][p]+sum[j])#include <stdio.h>#include <string.h>#include <iostream>#define MAX(a,b) (a)>(b)?(a):(b)using namespace
阅读全文
摘要:题意:一个n*m的矩阵,每个格子是0或者1,1表示土壤肥沃可以种植草地,0则不可以。在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况)本来我用dfs来搜索,函数参数里加一个bool型,表示当前是否放牛,但是后来发现必行tle,因为情况会场多O(n^n),后来搜了下,发现用状态压缩由于可行的状态是没有相邻的1,所以先把所有的行状态找到,就是二进制中木有相邻1的数字,放到cnt数组里接下来输入土地状态的时候需要取反(0变成1,1变成0),为的是,如果某一个可行状态与当前行进行&操作后,如果不为0,那么表示在1的位置上放了牛但是此时的1
阅读全文
摘要:树形dp的第一道题,本来感觉dp类题目就够难了,dp方程不好找,没想到又来个树形dp,好吧,看了答案姑且看懂了,自己编了下a了树形dp有几点需要注意:1 找到状态转移方程2 考虑好边界条件这道题目的意思就是给你一棵树,问你至少删除几条边,可以得到一个p个节点构成的子树...首先用vector模拟二维数组存储边的结构,然后dp[root][p]表示以root为根的树得到一个p节点的子树需要删除的最少边数初始化时候都为INF,但是需要注意点初始化dp[root][1]=0,因为在每次遍历root的孩子时候如果不删除,那么至少要保留一个节点root本身所以可以得到,v为root的一个孩子1 如果切,
阅读全文
摘要:Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。 设计一个程序,计算Jimmy到底地面时可能的最早时间。 Input第一行是测试数据的组数t(0 <= t <= 20)。每组测试数据的第一行是四个整数N,X,Y,MAX,用空格分隔。N是平台的数目(不包括地面),X和Y是Jimmy开始下落的位置的横竖坐标,MAX是一次下落的最大高度。接下来的N行每行描述一
阅读全文
摘要:给出几种颜色需求的ml量,然后最后一个数是灰色需求量,灰色可以由任何三中不同颜色的颜色组成,每个颜料盒有所给出的颜色的炎凉50ml问最少给出几个颜料盒,可以组成所需求颜色 显然贪心可以解决,先求出满足的普通色所需的最小盒数,然后把剩余颜料从大到小排列,那前三种每个取出1ml组成1ml的灰色,在这里本来我是把选出三个颜色中,直接选取第三个(最小容量)的所有容量k,组成kml的灰色,后来发现不行,贪心必须每次都要要求最好所以每次1ml来选才能达到要求#include <stdio.h>#include <string.h>#include <algorithm>
阅读全文
摘要:给出一个整数序列,求出两个连续序列和的和最大值,这两个序列不必连续,但是不能交叉可以先正向求一次最大和,dp[i]表示i之前包括i的最大连续和的值然后反向求一次最大和,相加dp[i]对比求出最大值#include <stdio.h>#define MIN -9999999int main(){ int T; scanf("%d",&T); int sum,tmp,n,ans; int num[50001],dp[50001]; while(T--) { scanf("%d",&n); sum=0; tmp=MIN; for(i
阅读全文
摘要:给出一些不合法的括号表达式,然你求出最短的合法的s[]是读入的字符串f[i][j]是i到j的最少的添加数c[i][j]是对应的添加方案分几种情况s[i] == '[' 在右端添 ']' 并求解 s[i + 1][j]s[i] == '('s[j] == ')'s[j] == ']'类似处理s[i] == '[' && s[j] == ']' ,求解s[i + 1][j - 1] s[i] == '(' && s[j] == ')
阅读全文
摘要:题目描述,给出一个整数,问你有多少种情况能把这个整数拆分成对称并且是双峰序列的和?1: (1) 2: (2), (1 1) 3: (3), (1 1 1) 4: (4), (1 2 1), (2 2), (1 1 1 1) 5: (5), (1 3 1), (1 1 1 1 1) 6: (6), (1 4 1), (2 2 2), (1 1 2 1 1), (3 3), (1 2 2 1), ( 1 1 1 1 1 1) 7: (7), (1 5 1), (2 3 2), (1 1 3 1 1), (1 1 1 1 1 1 1) 8: (8), (1 6 1), (2 4 2), (1 1 4
阅读全文
摘要:#include <queue>#include <stack>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <algorithm>using namespace std;int a[22];int dp[2500000];int main(){ int n; scanf("%d&quo
阅读全文
摘要:给出一个二维数组,让你求出最长递减序列长度,可以四个方向行走,起点任意明显的dp,用dp+递归比较好,循环的话还要找出递增的起来,比较麻烦循环出四个方面的最长序列然后len[i][j]=max(len[上],下,左,右)+1;#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#define N 101using namespace std;int map[N][N],len[N][N];int dir[4][2]={{-1,0},{0,1},{1,0
阅读全文
摘要:给出几种硬币的价值以及他的数量,然后给出一个最大钱,问你所给的钱能组成1到最大钱的值有多少种?多重背包,直接套用多重的模版#include <stdio.h>#include <string.h>#define N 105#define M 100005#define MAX(a, b) (a > b ? a : b)int a[N], c[N], f[M];void Complete(int cost, int weight, int m){ for(int i = cost; i <= m; i++) f[i] = MAX(f[i], f[i - cos
阅读全文
摘要:三国志TimeLimit: 5000MS MemoryLimit: 32768 KbDescription 《三国志》是一款很经典的经营策略类游戏。我们的小白同学是这款游戏的忠实玩家。 现在他把游戏简化了一下,地图上只有他一方势力,现在他只有一个城池,而他周边有一些无人占有的空城,但是这些空城中有很着不同数量的同种财宝。我们的小白同学虎视眈眈的看着这些城池中的财宝。 按照游戏的规则,他只要指派一名武将攻占这座城池,里面的财宝就归他所有了。不过,一旦攻占领这座城池,我们的武将就要留守,不能撤回。因为我们的小白手下有无数的武将,所以他不在乎这些。 从小白的城池派出的武将,每走一公里的距离就要消耗一
阅读全文
摘要:题目大意就是,给出一个板子的长宽,如果一个板子可以放到另外一个上面(长宽均小于此块),那么可以认为此板子加工时候不话费时间if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2). 根据题意,把板子按照l的值进行从小到达排序
阅读全文
摘要:浙大月赛的一题,题目的意思是研究人员发现有N个原子两两组合会发生反应产生能量,且其中一个会被和谐掉,给出一个矩阵map,其中map[i][j]表示原子i与j发生反应且原子j被和谐掉所释放的能量,问给定的n个原子反应最多能产生多少能量。可以用一个二进制表示一个状态,1表示被和谐,那么dp[6] 6-110 表示第1个和第二个原子被和谐,然后用一个数组来存储某个原子被和谐的状态intcst[11]={1,2,4,8,16,32,64,128,256,512,1024};这个的作用是,如果在某个状态下,第i个原子没被和谐,那么这个状态&cst[i]==0然后循环所用状态,每次循环找出两个没被
阅读全文
摘要:Input输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。Output对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行把时间按照end的时间从小到达排序,之后贪心解决View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include &
阅读全文