中文题意不多解释了。
建一个二维dp数组,dp[ i ][ j ]表示第 i 秒落在 j 处一个馅饼。我们需要倒着DP,为什么呢,从 0秒,x=5处出发,假如沿数组正着往下走,终点到哪里我们是不知道的,沿这个路线能最大值,下一秒就未必是最大值。但是我们知道起点,所以我们从终点开始走,走到dp[ 0 ][ 5 ]为止。由于这个总路线存在着诸多未知情况,但是有一点我们可以确定:
i , j
i+1,j-1 i+1,j i+1,j+1
对于dp[ i ][ j ]这个点,想走到下一步,肯定要加上下一步的更大的值,这个东西是不会变的。所以从最后时间点max-1(其实从max也是可以过的)开始往上走,每次取 i ,j 的下一行三个数的最大值,再加上i,j就可以了。得到方程:
dp【i】【j】+= max(dp【i+1】【j-1】,dp【i+1】【j】,dp【i+1】【j+1】);
最后输出dp[0][5]这个起点就可以了。
Alex doesn't like boredom. That's why whenever he gets bored, he comes up with games. One long winter evening he came up with a game and decided to play it.
Given a sequence a consisting of n integers. The player can make several steps. In a single step he can choose an element of the sequence (let's denote it ak) and delete it, at that all elements equal to ak + 1and ak - 1 also must be deleted from the sequence. That step brings ak points to the player.
Alex is a perfectionist, so he decided to get as many points as possible. Help him.
Input
The first line contains integer n (1 ≤ n ≤ 105) that shows how many numbers are in Alex's sequence.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 105).
Output
Print a single integer — the maximum number of points that Alex can earn.
Examples
Input
Output
Input
Output
Input
Output
Note
Consider the third test example. At first step we need to choose any element equal to 2. After that step our sequence looks like this [2, 2, 2, 2]. Then we do 4 steps, on each step we choose any element equals to 2. In total we earn 10 points.
题意:删除ak,那么这个数组所有的ak+1,ak-1都被删除,同时得到ak分。求能得到的最大分数。
对每个数进行了桶排序num。这样对后面的差大于1的数没有后效性。。从0位置开始向右消去,那么要消除一个数 i ,如果i-1被消去,那么i自然也不存在,此时dp[i] = dp[i-1],分数不变,因为i没得删。如果i-1没被删去,那么 dp[ i ] = dp[ i-2 ]+num[i]*i;
最长递增子序列。
比如对于{5,6,7,4,2,8,3} 那么最长就是{5,6,7,8}长度为4.
HDU 1257 最少拦截系统
中文题意,求最长递增子序列。
求最长递增子序列的和
这个样例很误导人啊,这个题意呢,就是从起点跳到终点,保持递增跳而且得分最大。注意,起点和终点是不计分的;
模板改一下就好了,之前求的是序列长度。这里求和,那么只要把dp初始化a[ ],依然还是探讨每个数选还是不选的问题。转移方程:
if(a[i]>a[j])
dp[ i ]=max(dp[ i ],dp[ j ]+a[ i ])
A
我们称长度为
给定一个长度为
输入描述
第
第
输出描述
输出一行
样例解释 1
区间[1,2] [2,3] [3,2] [2,1] [2,3,2] 满足题意,所以共有 5 个波浪序列。
这个题用DP解比较简单,其他的解法我并没有看懂。所谓波浪,单独一个数字不能算,两个数字一定算上。我们的二维dp,j=0表示下降或相等,j =1 表示上升。i 从0到n
转移方程:
拿样例来解释一下:
我们可以写出这么个东西: 0 1
1 0 1
2 0 1
3 2 0
4 1 0
sum逐个加就是答案。 第一步,从 i =1 开始,出现上升,则dp[1][1]=dp[0][0]+1;
第二步,i=2 , 2->3还是上升,但是dp[2][1]不能承接上一个dp[1][1],因为三个上升数不是波浪,需要承接dp[0][1],再加1(差不多算是重置吧)
第三步, i =3 ,3->2,出现下降,dp[3][0]=dp[2][1]+1=2,这里说明一下,dp[2][1]存的是2->3,+1里的这个1,是新的3->2,原来的2->3接上3->2,数目还是那个数目,既dp[3][0]=dp[2][1]+1=2。
总的来说,这个转移方程中,+1就是加的当前新的波浪,而上一步的dp,是之前的波浪接上了此次的新波浪,数目依然是上一个dp,但是样子已经不同了,所以要用sum进行累加。
区间DP:
给一堆石子,相邻的合并,问最后得到的最小花费,花费具体算法在题里。
对于此题,根据常识,对于最终状态,是由两团合并的。所以定义dp[i][j]表示区间i-j合并的最小值。
二堆合并:dp[1][2]=dp[1][1]+dp[2][2]+sum[1~2];
即dp[i][i+1]=dp[i][i]+dp[i+1][i+1]+sum[i~i+1];
三堆合并:dp[1][3]=min(dp[1][1]+dp[2][3],dp[1][2]+dp[3][3])+sum[1~3];
dp[i][i+2]=min(dp[i][i]+dp[i+1][i+2],dp[i][i+1]+dp[i+2][i+2])+sum[i~i+2];
综上推广到第i堆到第j堆的合并,dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
三个for,相当于遍历每一个长度的区间。
感觉有点floyed 的意思.....找中转点
还是区间DP
题意就是,给定字符串s,长度为m,由n个小写字母构成。在s的任意位置增删字母,把它变为回文串,增删特定字母的花费不同。求最小花费。
对于样例1: 3 4
abcb
a 1000 1100
b 350 700 c 200 800
在abcb首端插入bcb花费最小。