动态规划入门练习
2017-03-10 21:05
246 查看
动态规划入门专题
POJ 2533 Longest Ordered Subsequence最长单调上升子序列
状态转移方程:d[i] = max{0, d[j] | j < i, a[j] < a[i]} + 1;
int main() { int n, a , d ; while(cin >> n) { for(int i = 0; i < n; ++i) { cin >> a[i]; d[i] = 1; } int maxValue = 1; for(int i = 1; i < n; ++i) { for(int j = 0; j < i; ++j) { if(a[j] < a[i]) d[i] = max(d[i], d[j]+1); } maxValue = max(d[i], maxValue); } cout << maxValue << endl; } return 0; }
POJ 1088 - 滑雪
状态转移方程:d[x][y] = {max(d[x][y] , d[xi][yi]) | 0 < i < 4, h[xi][yi] > d[x][y]} ,其中(xi, yi)为从(x, y)向四个方向移动一格的坐标
//记忆化搜索 #include <stdio.h> #include <string.h> #define FOR(i, n) for(int i = 0; i < n; i++) #define max(x, y) x > y ? x : y const int N = 100; int r, c; int h[N+5][N+5]; int d[N+5][N+5]; int dir[4][2] = {{0,-1}, {0,1}, {-1,0}, {1,0}}; int check(int x, int y) { return x < 0 || x >= r || y < 0 || y >= c; } int dfs(int x, int y) { if(d[x][y] == -1) { d[x][y] = 1; FOR(i, 4) { int x1 = x + dir[i][0], y1 = y + dir[i][1]; if(!check(x1, y1) && h[x1][y1] > h[x][y]) d[x][y] = max(d[x][y], dfs(x1, y1) + 1); } } return d[x][y]; } int main() { int maxHigh; while(scanf("%d%d", &r, &c) != EOF){ maxHigh = 0; memset(h, 0, sizeof(h)); memset(d, -1, sizeof(d)); FOR(i, r) FOR(j, c) scanf("%d", &h[i][j]); FOR(i, r) FOR(j, c) { dfs(i, j); maxHigh = max(maxHigh, d[i][j]); } printf("%d\n", maxHigh); } }
HDU 1421 - 搬寝室
对于a < b < c < d序列, 有(ab, cd)、(ac, bd)、(ad, bc)三种组合,可以推出(ab, cd)是最优的选择
状态转移方程:
dp
[k] = min(dp[n-1][k], dp[n-2][k-1] + (a[i-1] - a[i-2]) ^ 2) {k != n>>1};
if(n是偶数) dp
[n>>1] = dp[n-2][k-1] + (a[i-1] - a[i-2]) ^ 2
#define SQ(x) ((x) * (x)) using namespace std; const int N = 1005; int dp[N<<1] ; int main() { int n, k; int a[N<<1]; while(cin >> n >> k) { for(int i = 0; i < n; ++i) cin >> a[i]; sort(a, a+n); dp[2][1] = SQ(a[1] - a[0]); for(int i = 3; i <= n; ++i) { for(int j = 1; j <= (i>>1); ++j){ dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + SQ(a[i-1] - a[i-2])); } if(~i&1) dp[i][i>>1] = dp[i-2][(i>>1)-1] + SQ(a[i-1] - a[i-2]); } cout << dp [k] << endl; } return 0; }
POJ 2247 - Humble Numbers
A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, … shows the first 20 humble numbers.
状态转移方程:d[0] = 1, d
= min(d[p[0]] * 2, d[p[1]] * 3, d[p[2]] * 5, d[p[3]] * 5),其中p[i]表示序列中数的位置,对于丑数序列中的每一个数n, n * 2, n * 3, n * 5, n * 7也都属于丑数序列,注意去重,如2*3 = 3*2
const int N = 5842; int d[N+5]; int p[4]; int k[4] = {2, 3, 5, 7}; int main() { int n = N; d[0] = 1; while(n--) { int minValue = d[p[0]] * k[0]; for(int i = 1; i < 4; ++i) { int temp = d[p[i]] * k[i]; minValue = minValue > temp ? temp : minValue; } // remove repeat number for(int i = 0; i < 4; ++i) if(d[p[i]]*k[i] == minValue) p[i]++; d[N-n] = minValue; } while(scanf("%d", &n) != EOF) { if(n == 0) break; if(n % 10 == 1 && n % 100 != 11) printf("The %dst humble number is %d.\n", n, d[n-1]); else if(n % 10 == 2 && n % 100 != 12) printf("The %dnd humble number is %d.\n", n, d[n-1]); else if(n % 10 == 3 && n % 100 != 13) printf("The %drd humble number is %d.\n", n, d[n-1]); else printf("The %dth humble number is %d.\n", n, d[n-1]); } }
相关文章推荐
- 动态规划入门(二)DP 基本思想 具体实现 经典题目 POJ1088 POJ1163 POJ1050
- 很特别的一个动态规划入门教程
- 数据结构 练习 19-活动选择问题的实现(动态规划 和 贪心)
- 动态规划入门——Max Sum
- poj 1163 The Triangle (动态规划入门题)
- 动态规划练习二:HDU 1160 FatMouse's Speed
- 动态规划入门——To The Max
- 【练习09】简单动态规划 1001 最大连续子序列
- 很特别的一个动态规划入门教程
- 动态规划入门——Monkey and Banana
- 第十五章动态规划之“O(n^2)时间寻找n个数构成序列的最长递增子序列”(练习15.4-5)
- 动态规划练习 6
- 动态规划练习 5
- 【练习09】简单动态规划 1002 Max Sum
- 动态规划练习 索引
- 动态规划入门(四)DP 基本思想 具体实现 经典题目 POJ1160 POJ1037
- 动态规划练习 3
- 防卫导弹(动态规划入门题)
- 【练习09】简单动态规划 1004 命运
- 动态规划入门——Doing Homework