dp

UVA 10003 Cutting Sticks

寵の児 提交于 2020-03-03 22:00:53
题意:在给出的n个结点处切断木棍,并且在切断木棍时木棍有多长就花费多长的代价,将所有结点切断,并且使代价最小。 思路:设DP[i][j]为,从i,j点切开的木材,完成切割需要的cost,显然对于所有DP[i][i+1]=0,记w[i][j]为从i,j点切开的木材的长度,因此可以枚举切割点,dp[i][j]=min(dp[i][k]+dp[k][j])+w[i][j],k就是枚举的切割点. AC代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int SIZEN=55; 6 const int INF=1<<30; 7 int x[SIZEN]; 8 int dp[SIZEN][SIZEN]; 9 int w[SIZEN][SIZEN]; 10 void init() 11 { 12 memset(dp,-1,sizeof(dp)); 13 } 14 int dfs(int l,int r) 15 { 16 if(dp[l][r]!=-1) 17 return dp[l][r]; 18 int ans=INF; 19 for(int i=l+1; i<r; i++) 20 { 21 ans=min(ans,dfs(l,i)+dfs(i,r));

221. Maximal Square(dp)

ぃ、小莉子 提交于 2020-03-02 21:51:16
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. Example: Input: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Output: 4 用dp来记录以i,j为右下角元素时最大的matrix。状态转移方程比较trick Solution: class Solution(object): def maximalSquare(self, matrix): """ :type matrix: List[List[str]] :rtype: int """ res = 0 dp = [[0 for i in range(len(matrix[0]))] for j in range(len(matrix))] for i in range(len(matrix)): for j in range(len(matrix[0])): dp[i][j] = 1 if matrix[i][j]=='1' else 0 if i>0 and j>0 and matrix[i][j]=='1': dp[i][j] = 1 + min(dp[i-1][j-1],min(dp[i-1]

Pokemon Go Go(状压dp) ICPC North Central NA Contest 2017 B题

随声附和 提交于 2020-03-02 11:30:48
题目链接: Pokemon Go Go 题目大意: 一个抓宝可梦的游戏,玩家一开始站在(0, 0)点,接着输入n表示宝可梦的数量,接着输入n行,每行两个整数和一个字符串,表示这个种类的宝可梦以及当前这只所在的坐标(这n只里面可能有好几只同种的宝可梦在不同位置)。 题目问玩家从(0, 0)开始,只能上下左右走,要把每种宝可梦都抓到一只且仅一只,最后回到(0, 0),最短的路程是多少。 样例输入 5 5 9 Eevee 20 20 Flareon 1 1 Flareon 1 8 Jolteon 2 8 Umbreon 样例输出 28 样例解释: The distance from (0,0) to (5,9) is 14 The distance from (5,9) to (2,8) is 4 The distance from (2,8) to (1,8) is 1 The distance from (1,8) to (1,1) is 7 The distance from (1,1) to (0,0) is 2 思路: n最大是25,宝可梦的种类最多就15,一个整数即可表示目前抓到的宝可梦集合的状态,因此可以状压dp。按状压dp的套路,其中一个参数是状压的整数,另一个则是最后加入这个集合中的宝可梦的编号。 所以 dp[i][j] 表示当前抓的宝可梦的集合是 i

HDU 1561 The more, The Better[树形dp/01背包]

与世无争的帅哥 提交于 2020-02-29 12:55:11
The more, The Better 时限:2000ms Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? Input 每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。 Output 对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。 Sample Input 3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7 6 2 2 0 0 Sample Output 5 13 从节点0出发,找到经过m个节点的最长链,实际上是m+1个节点,因为每次都要从0节点开始。从树的下面开始dp。 dp[u][w]表示在u的子树上选择w个节点,u节点是必选的。

HD1561The more, The Better(树形DP+有依赖背包)

吃可爱长大的小学妹 提交于 2020-02-29 12:54:55
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6765 Accepted Submission(s): 3978 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? Input 每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。 Output 对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。 Sample Input 3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7 6

hdu 1561(树形DP+背包)

為{幸葍}努か 提交于 2020-02-29 12:48:50
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6992 Accepted Submission(s): 4100 Problem Description ACboy 很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原 因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? Input 每 个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。 Output 对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。 Sample Input 3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7

CodeForces - 1137C Museums Tour

我的梦境 提交于 2020-02-28 23:28:27
题意: 给定一个 n n n 个点、 m m m 条边的有向图,给给定每周天数 d d d ,每个点处设有一个博物馆,给出每个博物馆在每周内的开放的情况,在某周第一天从 1 1 1 号点出发,走过一条边的时间恰都为一天,问最多能访问多少个博物馆。 ( n , m ≤ 1 0 5 , d ≤ 50 ) (n, m \leq 10^5, d \leq 50) ( n , m ≤ 1 0 5 , d ≤ 5 0 ) 链接: https://codeforces.com/contest/1137/problem/C 解题思路: 可以看出需要用 d p [ n ] [ d ] dp[n][d] d p [ n ] [ d ] 来解决问题,但图不是 D A G DAG D A G ,考虑缩点,为方便起见可以将 [ d ] [d] [ d ] 这一维拿出来直接分层建图,点 u + k d u + kd u + k d 表示星期 k k k 从 u u u 出发能访问的博物馆数,先 t a r j a n tarjan t a r j a n 缩点后化 D A G DAG D A G ,缩点时统计每个强连通分量里面的不同的博物馆数,那么就可以反拓扑序转移,答案为最长链。注意到每条链上的点已经本质不同,即若存在 ( u + k d ) → ( u + k ′ d ) (u + kd)

DP-01背包问题

微笑、不失礼 提交于 2020-02-28 12:37:46
思路:dp[i][j]表示的是前i个物品背包所能容纳不超过bagw的最大价值. #include<iostream> using namespace std; const int maxn = 100; int main() { int n,bagw; int w[maxn],v[maxn]; int dp[maxn][maxn]; cin>>n; for(int i = 0; i < n; i++) { cin>>w[i]>>v[i]; } cin>>bagw; for(int i = 0; i < n; i++) //初始化第一列(背包重为0时的最大价值) dp[i][0] = 0; for(int j = 0; j <= bagw; j++) //初始化第一行 { if(j >= w[0]) dp[0][j] = v[0]; else dp[0][j] = 0; } for(int i = 1; i < n; i++) { for(int j = 1; j <= bagw; j++) { if(j >= w[i]) { dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - w[i]] + v[i]); //选与不选取最大值 } else { dp[i][j] = dp[i - 1][j]; } } } cout<<dp[n-1][bagw]<

DP-01背包问题

别来无恙 提交于 2020-02-28 12:33:48
思路:dp[i][j]表示的是前i个物品背包所能容纳不超过bagw的最大价值. #include<iostream> using namespace std; const int maxn = 100; int main() { int n,bagw; int w[maxn],v[maxn]; int dp[maxn][maxn]; cin>>n; for(int i = 0; i < n; i++) { cin>>w[i]>>v[i]; } cin>>bagw; for(int i = 0; i < n; i++) //初始化第一列(背包重为0时的最大价值) dp[i][0] = 0; for(int j = 0; j <= bagw; j++) //初始化第一行 { if(j >= w[0]) dp[0][j] = v[0]; else dp[0][j] = 0; } for(int i = 1; i < n; i++) { for(int j = 1; j <= bagw; j++) { if(j >= w[i]) { dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - w[i]] + v[i]); //选与不选取最大值 } else { dp[i][j] = dp[i - 1][j]; } } } cout<<dp[n-1][bagw]<

DP-最长公共子序列

こ雲淡風輕ζ 提交于 2020-02-28 10:44:21
思路:dp[i][j]的含义为str1[0..i]与str2[0..j]的最长公共子序列长度. #include<iostream> #include<string> using namespace std; const int maxn = 100; int main() { string str1,str2; cin>>str1; cin>>str2; int dp[maxn][maxn]; for(int i = 0; i < str1.length(); i++) { if(dp[i - 1][0] == 1) { dp[i][0] = 1; continue; } if(str1[i] == str2[0]) { dp[i][0] = 1; } else dp[i][0] = 0; } for(int j = 0; j < str2.length(); j++) { if(dp[0][j -1] == 1) { dp[0][j] = 1; continue; } if(str1[0] == str2[j]) { dp[0][j] = 1; } else dp[0][j] = 0; } for(int i = 1; i < str1.length(); i++) { for(int j = 1; j < str2.length(); j++) { if(str1[i] ==