题目合集:动态规划DP
1.Max Sum Plus Plus
题目大意:输入一个m,n分别表示成m组,一共有n个数即将n个数分成m组,m组的和加起来得到最大值并输出。
解题思路:f[j] 表示当前分成i组前j个数的和最大值,dp[j-1] 表示分成i-1组前j-1个数的和最大值,状态转移方程为f[j]=max(f[j-1],dp[j-1])+a[j]; dp[j-1]=maxn; maxn=max(maxn,f[j]);
2.Monkey and Banana
题目大意:给出砖块长宽高,给出最大高度,砖块长宽从底往上严格递减。
解题思路:用vector<node>记录砖块数据并递增排序,遍历每块砖,如果以它(i)上面的砖(0<=j<=i-1)为底加它本身高度 dp[j]+v[i].h > dp[i],则更新dp数组。
3.Doing Homework
题目大意: 还有 n 个作业,完成某个作业需要一定的时间,而且每个作业有一个截止时间,若超过截止时间,输出扣分最少的时间及方案。
解题思路:状压dp,开结构体,i表示状态,j表示作业,若 i&(1<<j))==0,则取ne=i|(1<<j),dp[i].all表示扣的分,dp[i].d表示做到当前作业所处天数,递归输出。
4.Piggy-Bank
题目大意:完全背包问题,在给定重量的情况下,计算货币最小价值。
解题思路:遍历每个货币,状态转移方程:dp[j]=min(dp[j],dp[j-w[i]]+v[i]);(w表示重量,v表示价值,dp[j]表示重量为 j 的情况下背包中货币的最小价值)
5.免费馅饼
题目大意:有n个馅饼掉在小径上。在接下来的n行中,每行有两个整数x,T表示在第T秒有一个馅饼掉在x点上。求最多接到的馅饼数,一开始站在5(0-10共11个位置)
解题思路:a[x][t]表示t秒x位置的馅饼数,从最后一秒开始遍历,状态转移方程为f[j][i]=max(f[j-1][i+1],max(f[j][i+1],f[j+1][i+1]))+a[j][i];输出f[5][0]
6.Tickets
题目大意:现在有n个人要买电影票,给出每个人单独买票的时间,还有和前一个人一起买的时间,问最少花多长时间可以全部买完票。
解题思路:状态转移方程:f[i]=f[i-1]+a[i]; if(i>1)f[i]=min(f[i],f[i-2]+b[i-1]);
7.最少拦截系统
题目大意:导弹拦截系统每一发炮弹都不能超过前一发的高度,给出导弹高度,计算最少需要多少套拦截系统。
解题思路:遍历每个导弹,f[j]表示第j个拦截系统的当前拦截高度,j==当前拦截系统数+1时增加一套拦截系统。
8.FatMouse's Speed
题目大意:在老鼠序列中找出一个最大子序列并输出,使得老鼠的体重在增加,但是速度却在减慢。
解题思路:对速度递减排序,找出体重的最长递增子序列,dp数组开结构体,递归输出pre。
9.Jury Compromise
题目大意:选出的m个人,必须满足辩方总分和控方总分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可 。
解题思路:f[i][j][k]表示从前i个人中选j个人且总差为k的所有方案中的总分最大的方案的总分,输入——维护f数组——找最小差值v——找入选的人——计算人选的两个总分——输出。
10.Treats for the Cows
题目大意:给你n个数字,每次可以取出最左端的数字或者最右端的数字,一共取n次。第i次取的数字x可以获得i*x的价值。输出最大总价值。
解题思路:区间dp,f[i][j]表示区间i~j的总价值之和,状态转移方程为f[i][j]=max(f[i+1][j]+a[i]*(n-j+i),f[i][j-1]+a[j]*(n-j+i));
11.FatMouse and Cheese
题目大意:找到一条递增路线,使得价值和最大。(n阶方阵)
解题思路:记忆化搜索,递归寻找maxn=max(maxn,dfs(dx,dy));返回dp[x][y]=maxn+mp[x][y];
12.Help Jimmy
题目大意:Jimmy在时刻0开始下落,落到某个平台上时,选择让它向左还是向右跑,每次下落的高度不能超过MAX米,计算Jimmy到达地面时可能的最早时间。
解题思路:将平台按高度从低到高排序,第i块下方有平台m时,选择min(left(m),right(m))+i至m下落时间。
13.Milking Time
题目大意:N个点,M个区间,每个区间[L, R]的权值为w 从区间中选出一个子集,使得任意两个区间间隔至少为k,求最大的区间权值和。
解题思路:将区间间隔加到权值w中,区间从小到大排序,dp[j]表示前j个区间权值和,状态转移方程为
14.Making the Grade
题目大意:求将一个序列变为不递减或不递增序列的最小花费。
解题思路:将一个数变化的最少花费肯定是变为数列中已有的第一个比它大或比它小的数。所以先排序,dp[i][j]代表选取到第i个,最后一位(最大)的是第a[j]的最小花费,转移方程为 dp[i][j] = min(dp[i-1][1~j]) + |a[i]-b[j]|,用MIN=min(MIN,dp[i-1][j-1])转移最小值。