2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) . \(T\) ,都以 \(.\) 结尾,求 \(S\) . \(T\) 最长公共子序列的长度及个数. 分析: 一顿操作猛如虎,一看分数250--爆零了.原本就没准备拿几分,结果令人心塞. 第一问就是求最长公共子序列长度,数据范围比较小, \(O(n^2)\) 就行,上来就是一顿树状数组+LIS,…
给你n个数,让你任选K个,使得它们乘起来以后结尾的0最多. 将每个数的因子2和因子5的数量求出来,记作a[i]和b[i]. 答案就是max{ min{Σa[i],Σb[i]} }(a[i],b[i]是选择的那些数). 暴力dp是f(i,j,k)表示前i个数,选j个,其中包含k个5的情况下,最多能包含多少个2. 转移是f(i,j,k)=max{ {f(t,j-1,k-b[i]}+a[i]}(1<=i<t) , f(i-1,j,k) },时间是O(18 * n^3),但空间存不下. 注意第二维为j…
给一字符串,问最少加几个字符能够让它成为回文串. 比方 Ab3bd 最少须要两个字符能够成为回文串 dAb3bAd 思路: 动态规划 DP[i][j] 意味着从 i 到 j 这段字符变为回文串最少要几个字符,枚举子串长. if str[i] == str[j]: DP[i][j] = DP[i + 1][j - 1] else: DP[i][j] = min( DP[i + 1][j], DP[i][j - 1] ) + 1 注意: 长度较大为 5000,二维数组 5000 * 5000 须要将…
题意是说,给定一个字符串,问至少还需要插入多少个字符才能使得该字符串成为回文字符串. 这道题一开始做的时候用了一个简单的动态规划,开了一个5000*5000的数组,用递归形式实现,代码如下: 其中d[i][j]表示i到j所需要插入的字符数.然而数组开得太大直接报MLE.因此想到用滚动数组来解决. MLE代码如下: #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> u…
题目链接:https://cn.vjudge.net/problem/HDU-1024 题意 给n, m和一个序列,找m个不重叠子串,使这几个子串内元素和的和最大. n<=1e6 例:1 3 1 2 3 答:6 (唯一的子串1 2 3) 思路 先顺便记录一下动态规划的一般解题思路: 原问题->子问题->状态->转移->边界 再顺便记录一下最大值最小化这类问题套路解法: 二分 贪心 不能二分的问题,贪心八九不离十. 一般是AB和BA这两个元素的顺序,不影响前后变化时,直接算目标…
Max Sum Plus Plus HDOJ-1024 动态转移方程:dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j]) (0<k<j) 其中dp[i][j]表示前i个数分为j个子段的最大值 转移有两个方向:一个是分为i个子段,第j个属于第i个子段.另一个转移方向就是第j个单独形成一个子段,前k(0-j)个组成i-1个子段. 由于本题n太大,而m也没有给出,所以按照上面的想法需要有三重循环,会超时.所以需要使用滚动数组. 注意第二维需要正序遍历…
PROBLEM D - Round Subset 题 OvO http://codeforces.com/contest/837/problem/D 837D 解 DP, dp[i][j]代表已经选择了i个元素,当2的个数为j的时候5的个数的最大值 得注意最大值(貌似因为这个喵呜了一大片喵~☆) #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include…
Max Sum Plus Plus 题意:题意理解了老半天,这里是说在给定数列中,取m组子数列,不能有重复,使得这些子序列的和最大: 就比如m=2时候,1 /2/-4/5/6.可以不用拿-4的意思: 思路:这道题的思路是动态规划,递推: 状态dp[i][j] 表示有前j个数,组成i组的和的最大值. 决策: 第j个数,要么包含在第i组里面,要么自己独立成组. 其中最后一组包含a[j].(这很关键) 则状态转移方程为:(在二维图中,就是要么从左边取,要么取上一行的最大值,下式中,左边max是包含在第…
为了肾六 时间限制:4000 ms  |  内存限制:210535 KB 难度:2 描述 最近肾六很流行,goshawk看身边的朋友都用上了apple.自己还用着W年前的Samsung.于是决定去IT公司打工,都是为了肾六.现在上司让他解决下面的一个小问题,但是goshawk没学好算法,被这个问题难住了,聪明的你帮帮他吧. 给一个n个整数的序列p1,p2,p3.....pn.你要以下面的方式选k对整数. < ... < lk ≤ rk ≤ n; ri - li + 1 = m),  为了让这个…
显然将扩张按从大到小排序之后,只有不超过前34个有效. d[i][j]表示使用前i个扩张,当length为j时,所能得到的最大的width是多少. 然后用二重循环更新即可, d[i][j*A[i]]=max(d[i][j*A[i]],d[i-1][j]); d[i][j]=max(d[i][j],d[i-1][j]*A[i]); 当某次更新时,检验其符合了答案的条件,就输出. 显然可以用滚动数组优化到空间为线性. 注意爆int的问题. 此外,瞎几把搜+花式剪枝也能过. #include<cstd…