算法课复习 -- dp

HDU #2602 : Bone Collector

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2602

题意:n个东西,每个东西都有它的大小和价值。给定最大容量v,问容量为v的情况下最大价值为多少。

思路:最基本的背包类,要化成一维数组做的话从dp[n]往dp[1]就可以。

dp[i][j]:前i个东西容量为j时的最大价值。

dp[i][j] = max( dp[i][j] , dp[i][j-v[i]] + cost[i] );

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define P pair
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a= 0; j--) {
				if (j - v2[i] < 0)break;
				dp[j] = max(dp[j], dp[j - v2[i]] + v1[i]);
			}
		}
		printf("%d\n", dp[v]);
	}
	return 0;
}

 

OpenJ_Bailian #2533 : Longest Ordered Subsequence

传送门:http://bailian.openjudge.cn/practice/2533?lang=en_US

题意:给一个字符串,求它的最长上升子序列的长度。

思路:dp[i]:长度为i的上升序列中,第i位的最小值。

for循环,对于 dp[i-1] < s[j] 成立的最大的 i,dp[i] = min ( dp[i] , s[j] );

直接lower_bound二分来找更新位置也是可以的。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define P pair
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a

 

HDU #1159 : Common Subsequence

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1159

题意:给两个字符串,求最长公共子串。

思路:dp[i][j]:字符串s1从0-i位置,s2从0-j位置的公共子串的最大长度。

s[i]==s[j]:dp[i][j] = max ( dp[i][j] , dp[i-1][j-1] + 1 );

s[i]!=s[j]:dp[i][j] = max ( dp[i][j] , dp[i-1][j] , dp[i][j-1] );

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define P pair
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a> s1 >> s2) {
		int len1 = s1.length(), len2 = s2.length();
		cl0(dp);
		for (int i = 0; i < len1; i++) {
			for (int j = 0; j < len2; j++) {
				if (s1[i] == s2[j]) {
					if (i == 0 || j == 0)
						dp[i][j] = 1;
					else 					
						dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
				}
				else {
					if (i != 0)
						dp[i][j] = max(dp[i][j], dp[i - 1][j]);
					if (j != 0)
						dp[i][j] = max(dp[i][j], dp[i][j - 1]);
				}
			}
		}
		printf("%d\n", dp[len1 - 1][len2 - 1]);
	}
	return 0;
}

 

HDU #5092 : Seam Carving

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5092

题意:给出一个n行m列的矩阵。从顶上往下走,如果开始在i列,则下次只能在i-1、i、i+1列中任意一列。每个位置有一个数字,问怎么走才能使得一路上的数字之和最小。如果有相同的话取最靠右的方案。

思路:dp + 用pre数组记路。

pre记路的话,每次 dp[i][j] 更新的时候 pre[i][j] 也跟着更新,在最后利用 ans=pre[i--][ans]; 来还原。

dp[i][j]:走到第 i 行,第 j 列时的最小值。

dp[1][j] = a[1][j];

dp[i][j] = min( dp[i][j] , dp[i-1][j+k] );  ( -1 <= k <= 1 )

注意因为相同取最右,所以如果是从左往右则小于等于的时候也要更新。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define P pair
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a m)continue;
					if (dp[i - 1][j + k] + a[i][j] <= dp[i][j]) {
						dp[i][j] = dp[i - 1][j + k] + a[i][j];
						pre[i][j] = j + k;
					}
				}
			}
		int ans = 1;
		for (int i = 2; i <= m; i++) {
			if (dp[n][i] <= dp[n][ans])
				ans = i;
		}
		stack s;
		while (ans != 0) {
			s.push(ans);
			ans = pre[n--][ans];
		}
		printf("Case %d\n", _);
		printf("%d", s.top()); s.pop();
		while (!s.empty()) {
			printf(" %d", s.top());
			s.pop();
		}
		printf("\n");
	}
	return 0;
}

 

UVA #10003 : Cutting Sticks

传送门:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=944

题意:给出木头总长度和需要切的点,每次切一块长度为n的木头需要花费n,问最少花费多少。

思路:区间dp。

dp[i][j]:点 i 到点 j 范围内的最小花费。点0为0位置,点n+1为l位置。

dp[i][j] = min ( dp[i][j] , dp[i][k] + dp[k][j] + cost[i][j] ); ( i < k < j )

最终答案为dp[0][n+1]。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define P pair
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a n + 1)break;
				for (int i = s + 1; i <= e - 1; i++)
					dp[s][e] = min(dp[s][e], dp[s][i] + dp[i][e] + a[e] - a[s]);
			}
		}
		printf("The minimum cutting is %d.\n", dp[0][n + 1]);
	}
	return 0;
}

 

你可能感兴趣的:(算法课复习,dp)