dp

sicily 1563 GECKO

别说谁变了你拦得住时间么 提交于 2021-01-13 09:49:57
Description During the rainy season, one of the walls in the house is infested with mosquitoes. The wall is covered by h × w square tiles, where there are h rows of tiles from top to bottom, and w columns of tiles from left to right. Each tile has 1 to 1000 mosquitoes resting on it. A gecko wants to eat as many mosquitoes as possible, subject to the following restrictions. It starts by choosing any tile in the top row, and eats the mosquitoes in that tile. Then, it moves to a tile in the next lower row, eats the mosquitoes on the tile, and so on until it reaches the floor. When it moves from

hdu2045 不容易系列三——LELE的RPG难题 (递推方程)

点点圈 提交于 2020-11-10 07:55:33
本文出自: blog.csdn.net/svitter 原题: http://acm.hdu.edu.cn/showproblem.php?pid=2045 题意:中文不用我说了吧。 这个题目的关键就在于递推方程——以及错误的测试数据 首先这个题目就是简单的置换群着色问题—— 去除了反转的问题,难一点的大家可以看P197(离散数学,高等教育出版社) 我在做这个题目的时候首先被f [ 1 ] = 3 困扰了。。拜托,根本不符合题意好吗- =一个格子能说是首尾颜色不同吗? 后来写错了递推方程——f [ n ] = f [ n - 1 ] + 3 * f [ n - 2 ],把 f [ n - 1 ] 的情况多考虑了一遍- = 。 正确的方程应该是 —— f [ n ] = f [ n - 1 ] + 2 * f [ n - 2 ] , n >= 4; (去除了f [ 1 ] = 3 这个坑爹的干扰。) 写成lln是为了防止超范围——写完以后记得DEBUG一下看看有没有超范围—— 代码: #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define lln long long int lln f[51]; void ace() { memset(f, 0x3f, sizeof(f

动态规划-1620. 收集硬币

感情迁移 提交于 2020-04-08 08:47:49
2020-04-08 07:45:18 问题描述: 给定一个 n * m 个的矩阵,矩阵的每个位置有一定数量的硬币,你从 (0,0) 位置出发,每次只能 往右 或者 往下 走,当他经过某个格子的时候,可以得到这个格子上的所有硬币,当它走到第 (n-1,M-1) 位置时游戏结束,在游戏开始前,你有 ķ 次机会,可以交换某两个格子中的硬币数量中,k次机会不一定要使用完,求从(0,0)走到第(n-1,M-1)所能得到的最大的硬币数量。 样例 输入: matrix = [[9,9,9,0,0],[0,0,9,0,0],[0,0,0,0,0],[0,0,9,0,0],[9,0,9,9,9]] k = 1 输出:81 注意事项 2≤n,m≤50 0<=k<=20 0<=matrix[I][j]<=1000000 问题求解: int nums[55]; int dp[55][55][25][25]; int collectingCoins(vector<vector<int>> &matrix, int k) { // Write your code here int n = matrix.size(); int m = matrix[0].size(); memset(dp, -0x3f,sizeof(dp)); dp[0][0][0][0] = matrix[0][0], dp[0][0]

4.6 每日一题题解

偶尔善良 提交于 2020-04-06 09:01:26
三角形 题目链接: https://ac.nowcoder.com/acm/contest/4911/B 涉及知识点: 背包dp solution: 背包是dp算法中非常经典的一个问题(如果打算学dp的同学必须要学会背包问题),具体的大家可以看我发在群里的背包九讲pdf 关于这道题目,我们可以对每一个宝箱做一个背包 题目要求从每一个宝箱中有且只能取一个,所以设dp[i][j]为枚举到第i个宝箱,可以获得钱数等于j的方案数 那么转移方程就等于 dp[ i ][ z ] += dp[ i-1 ][ z - a[ i ][ j ] ] ,初始化dp[ 0 ][ 0 ] = 1 i代表前i个宝箱,z代表可以获得z钱,a[ i ][ j ]代表枚举的第i个宝箱的第j个钱,dp[ i ][ z ]就等于前i个宝箱可以获得z钱的方案数 j的范围是0~10000,最后从小到达枚举dp[ n ][ j ],代表前n个宝箱中可以获得钱数等于j的方案数,不断和k做差就得到了答案 std: #include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 105; int a[maxn][maxn],dp[maxn][maxn*maxn],len[maxn]; int main() { int n , k

状态压缩 + 状压DP

你说的曾经没有我的故事 提交于 2020-03-29 06:22:54
该博客有大量复制内容,仅供自己学习、复习使用。 部分参考于: https://www.cnblogs.com/Tony-Double-Sky/p/9283254.html 简单介绍 状态压缩动态规划,就是我们俗称的 状压DP ,是利用 计算机二进制 的性质来描述状态的一种DP方式。 很多n*m矩阵问题都运用到了状压,同时,状压也很经常和BFS及DP连用,有了状态,BFS和DP就比较容易了。 状压其实是一种 很暴力的算法 ,因为他需要遍历每个状态,所以将会出现2^n的情况数量 我们用二进制的每一位代表一个对象, 对于n个对象,一共有 (1<<n)-1 个状态,而对于第i个对象进行操作的时候是 1<<(i-1) 。 P2622 关灯问题II(状压BFS) https://www.luogu.com.cn/problem/P2622 题解: https://www.cnblogs.com/jiamian/p/12589267.html P1879 [USACO06NOV]Corn Fields(状压DP) https://www.luogu.com.cn/problem/P1879 题解: https://www.cnblogs.com/jiamian/p/12590539.html 通过题目要求减少状态量 这可以说是状压的一大精华了。一般状压的题目会有大量的状态

爬楼梯

一曲冷凌霜 提交于 2020-03-21 09:17:11
746. Min Cost Climbing Stairs 数组的每个索引做为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i] (索引从0开始)。 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。 您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。 示例 1: 输入: cost = [10, 15, 20] 输出: 15 解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15。思路:位于位置i,可以花费cost[i]爬一阶楼梯,或者爬二阶楼梯。当只有一阶楼梯时,本身就处于终点,不需要再花费力气了。 1 class Solution(object): 2 def minCostClimbingStairs(self, cost): 3 """ 4 :type cost: List[int] 5 :rtype: int 6 """ 7 8 n=len(cost) 9 if(n==1): return cost[0] 10 11 dp=[0 for j in range(n+1)] 12 13 dp[1]=0 14 dp[2]=min(dp[1]+cost[1],cost[0]) 15 for i in range(3,n+1): 16 dp[i]=min

动态规划求子序列和子串问题

倾然丶 夕夏残阳落幕 提交于 2020-03-17 06:39:25
LeetCode子序列问题: 300. 最长上升子序列 ; 673. 最长递增子序列的个数 ; 1143. 最长公共子序列 ; 516. 最长回文子序列 LeetCode子串问题: 5. 最长回文子串 ; 14. 最长公共前缀 300. 最长上升子序列 int max(int a,int b){ return a>b?a:b; } int lengthOfLIS(int* nums, int numsSize){ int i,j,rst=0; int dp[numsSize+1]; if(numsSize<=1)return numsSize; for(i=0;i<numsSize;i++){ dp[i]=1; for(j=0;j<i;j++){ if(nums[i]>nums[j]){ dp[i]=max(dp[i],dp[j]+1); } if(rst<dp[i])rst=dp[i]; } } return rst; } 673. 最长递增子序列的个数 int max(int a,int b){ return a>b?a:b; } int findNumberOfLIS(int* nums, int numsSize){ int i,j,dp[numsSize+1],maxnum=0,cnt[numsSize+1]; if(numsSize<=1)return numsSize

剑指offer-20200313

烈酒焚心 提交于 2020-03-17 06:31:11
20200313 题目 :丑数 我们把只包含因子2、3和5的数称为丑数。按从小到大的顺序的第n个丑数。 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。 思路 :动态规划;需将前面的求得的丑数记录下来。后面的值等于前面的*2或*3或*5。 code class Solution { public int nthUglyNumber ( int n ) { int p2 = 0 , p3 = 0 , p5 = 0 ; int [ ] dp = new int [ n ] ; dp [ 0 ] = 1 ; //初始值 for ( int i = 1 ; i < n ; i ++ ) { //确保丑数从小到大排序。 dp [ i ] = Math . min ( dp [ p2 ] * 2 , Math . min ( dp [ p3 ] * 3 , dp [ p5 ] * 5 ) ) ; if ( dp [ i ] == dp [ p2 ] * 2 ) p2 ++ ; if ( dp [ i ] == dp [ p3 ] * 3 ) p3 ++ ; if ( dp [ i ] == dp [ p5 ] * 5 ) p5 ++ ; } return dp [ n - 1 ] ; } } 题目

Double Elimination CodeForces - 1314B dp

∥☆過路亽.° 提交于 2020-03-16 09:01:51
//f[i,j,f1,f2] //f1 和 f2 都是01数 //1表示剩下的人是喜欢的 //从j开始,长度为2^i个人,胜者组为f1,败者组为f2 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = ((1<<17)+1000); int n,k,fans[maxn]; int dp[18][maxn][2][2]; //初始化 void init() { for(int i=0; i<18; i++) { for(int j=0; j<maxn; j++) { for(int k=0; k<2; k++) { for(int z=0; z<2; z++) { dp[i][j][k][z]=-1e9; } } } } } int main() { init(); cin>>n>>k; for(int i=0; i<k; i++) { int x; cin>>x; fans[x-1]=1; } //枚举i for(int i=1; i<=n; i++) { //枚举人 区间长度 for(int j=0; j<(1<<n); j+=(1<<i)) { //等于1,也就是初始化的时候 if(i==1) { /

POJ 2288 Islands and Bridges(状压DP)题解

依然范特西╮ 提交于 2020-03-14 04:40:50
题意:n个点,m有向边,w[i]表示i的价值,求价值最大的哈密顿图(只经过所有点一次)。价值为:所有点的w之和,加上,每条边的价值 = w[i] * w[j],加上,如果连续的三个点相互连接的价值 = w[i] * w[j] * w[k]。不存在输出0 0。n <= 13。 思路:dp[state][i][j]表示state状态下,最后两个为i,j。 代码: #include<cmath> #include<set> #include<map> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double eps = 1e-8; const int maxn = 15 + 10; const int M = maxn * 30; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 1e4 + 7; int w[maxn]; int n, m; int g[maxn][maxn];