区间DP-由矩阵连乘所想到的
来源:互联网 发布:淘宝福袋怎么设置 编辑:程序博客网 时间:2024/05/11 15:35
1.最优三角剖分
#include <iostream>#include <sstream>#include <stdio.h>#include <algorithm>#include <string.h>#include <stack>#include <queue>#include <set>#include <math.h>#include <time.h>/*=======================================最优三角剖分dp[i][j] = min(dp[i][x] + dp[x][j] + w(i, x, j));i <= x <= j边界条件 dp[i][i + 1] == 0========================================*/#define flush(arr, i) memset(arr, i, sizeof(arr))typedef long long int64;using namespace std;const int MAX_ITEM = 110;const int oo = 0x7fffffff;//const int oo = 0x3f3f3f3f;int dp[MAX_ITEM][MAX_ITEM], wei[MAX_ITEM][MAX_ITEM];int GetWeight(int from, int mid, int to){ return wei[from][mid] + wei[from][to] + wei[mid][to];}int DP(int from, int to){ if(to - from == 1) return 0; if(dp[from][to]) return dp[from][to]; int ans = oo; for(int i = from + 1; i < to; i++) ans = min(ans, DP(from, i) + DP(i, to) + GetWeight(from, i, to)); return dp[from][to] = ans;}int main(){ freopen("0-data.txt", "r", stdin); int n; while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) scanf("%d", &wei[i][j]); flush(dp, 0); printf("%d\n", DP(0, n - 1)); } return 0;}2.最大m子段和
#include <iostream>#include <sstream>#include <stdio.h>#include <algorithm>#include <string.h>#include <stack>#include <queue>#include <set>#include <math.h>#include <time.h>/*=======================================最大m子段和9 39 8 7 6 5 4 3 2 117dp[k][p]表示前k个元素划分为p个子段最大值的最小值dp[k][p] = min{dp[k][p], max{dp[x][p - 1] + sum[x + 1][k]}}p - 1 <= x <= k - 1========================================*/#define flush(arr, i) memset(arr, i, sizeof(arr))typedef long long int64;using namespace std;const int MAX_ITEM = 110;const int oo = 0x7fffffff;//const int oo = 0x3f3f3f3f;int dp[MAX_ITEM][MAX_ITEM];int sum[MAX_ITEM];int DP(int k, int p){ if(p == 1) return dp[k][p] = sum[k]; if(dp[k][p]) return dp[k][p]; int tmp = 0; dp[k][p] = oo; for(int i = p - 1; i <= k - 1; i++) { tmp = max(DP(i, p - 1), sum[k] - sum[i]); dp[k][p] = min(dp[k][p], tmp); } return dp[k][p];}int main(){ int len, p; while(scanf("%d%d", &len, &p) != EOF) { flush(sum, 0); flush(dp, 0); int tmp; for(int i = 1; i <= len; i++) { scanf("%d", &tmp); sum[i] = sum[i - 1] + tmp; } printf("%d\n", DP(len, p)); } return 0;}3.石子合并问题
#include <iostream>#include <sstream>#include <stdio.h>#include <algorithm>#include <string.h>#include <stack>#include <queue>#include <set>#include <math.h>#include <time.h>/*=======================================石子合并问题自底向上,求步长为k的时候,步长为k - 1问题的解已知dp[i][j]表示i -> j的最优解 得分最多/最少要加上合并的石子总数作为最优值dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j] + sum[i][j]);========================================*/#define flush(arr, i) memset(arr, i, sizeof(arr))typedef long long int64;using namespace std;const int MAX_ITEM = 110;const int oo = 0x7fffffff;//const int oo = 0x3f3f3f3f;int dp[MAX_ITEM][MAX_ITEM];int sum[MAX_ITEM];int main(){ int len; while(scanf("%d", &len) != EOF) { for(int i = 1; i <= len; i++) scanf("%d", sum + i); sum[0] = 0; for(int i = 1; i <= len; i++) sum[i] += sum[i - 1]; flush(dp, 0); for(int sp = 1; sp <= len; sp++) { for(int i = 1; i + sp <= len; i++) { int j = i + sp; for(int k = i; k < j; k++) dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]); printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } } printf("%d\n", dp[1][len]); } return 0;}4.最大的算式[TYVJ]
#include <iostream>#include <sstream>#include <stdio.h>#include <algorithm>#include <string.h>#include <stack>#include <queue>#include <set>#include <math.h>#include <time.h>/*=======================================最大的算式dp[k][p] = max(dp[p - 1 ... k - 1][p - 1] * sum[k][p])表示前i部分插入p个乘号获取的最大值========================================*/#define flush(arr, i) memset(arr, i, sizeof(arr))typedef long long int64;using namespace std;const int MAX_ITEM = 110;const int oo = 0x7fffffff;//const int oo = 0x3f3f3f3f;int dp[MAX_ITEM][MAX_ITEM], sum[MAX_ITEM][MAX_ITEM];int num[MAX_ITEM];void getSum(int len){ flush(sum, 0); flush(dp, 0); for(int i = 1; i <= len; i++) { sum[i][i] = num[i]; for(int j = i + 1; j <= len; j++) sum[i][j] = sum[i][j - 1] + num[j]; }/* for(int i = 1; i <= len; i++) for(int j = i; j <= len; j++) j == len ? printf("%d\n", sum[i][j]) : printf("%d ", sum[i][j]);*/}int DP(int k, int p){ if(p == 0) { dp[k][p] = sum[1][k]; return dp[k][p]; } if(dp[k][p]) return dp[k][p]; int ans = 0; for(int i = p - 1; i <= k - 1; i++) ans = max(ans, DP(i, p - 1) * sum[i + 1][k]); dp[k][p] = ans; return ans;}int main(){ int len, p; while(scanf("%d%d", &len, &p) != EOF) { for(int i = 1; i <= len; i++) scanf("%d", num + i); getSum(len); printf("%d\n", DP(len, p)); } return 0;}5.最大k乘积问题
#include <iostream>#include <sstream>#include <stdio.h>#include <algorithm>#include <string.h>#include <stack>#include <queue>#include <set>#include <math.h>#include <time.h>/*=======================================最大k乘积问题dp[k][p] = max(dp[p - 1 ... k - 1][p - 1] * num[k][p])表示前i项分为j部分的最大乘积========================================*/#define flush(arr, i) memset(arr, i, sizeof(arr))typedef long long int64;using namespace std;const int MAX_ITEM = 110;const int oo = 0x7fffffff;//const int oo = 0x3f3f3f3f;int dp[MAX_ITEM][MAX_ITEM], num[MAX_ITEM][MAX_ITEM];char in[MAX_ITEM];int getNum(char *in){ int len = strlen(in); flush(num, 0), flush(dp, 0); for(int i = 1; i <= len; i++) { int mul = 0; for(int j = i; j <= len; j++) { mul = mul * 10 + in[j - 1] - '0'; num[i][j] = mul; } }/* for(int i = 1; i <= len; i++) for(int j = i; j <= len; j++) j != len ? printf("%d ", num[i][j]) : printf("%d\n", num[i][j]);*/}//前k个分为p部分int DP(int k, int p){ if(p == 1) { dp[k][p] = num[1][k]; return num[1][k]; } if(dp[k][p]) return dp[k][p]; int ans = 0; for(int i = p - 1; i <= k - 1; i++) ans = max(ans, DP(i, p - 1) * num[i + 1][k]); dp[k][p] = ans; return ans;}int main(){ int p; while(scanf("%s", in) != EOF) { getNum(in); scanf("%d", &p); int len = strlen(in); printf("%d\n", DP(len, p)); } return 0;}
0 0
- 区间DP-由矩阵连乘所想到的
- 区间DP-矩阵连乘问题
- poj 1651 区间dp+矩阵连乘DP
- DP---矩阵连乘
- DP+矩阵连乘
- DP--矩阵连乘
- 矩阵连乘 DP
- dp矩阵连乘
- 矩阵连乘DP
- Multiplication Puzzle(区间DP:类似矩阵连乘问题的DP模板)
- POJ 1651 Multiplication Puzzle (区间dp 矩阵连乘)
- 基于DP的矩阵连乘问题
- DP 矩阵连乘问题
- 矩阵连乘DP模型
- zoj1276矩阵连乘dp
- 矩阵连乘问题 DP
- DP---矩阵连乘问题
- 矩阵连乘问题 DP
- DateTime获取当地时间
- P1002 谁拿了最多的奖学金
- eclipse或myeclipse创建不同的项目
- OI省选知识
- UNITY 5.2 HideFlags
- 区间DP-由矩阵连乘所想到的
- hdu1254 推箱子(广搜bfs)
- 使用servlet过滤器播放amr音频
- Matlab 的fspecial函数用法
- C/C++ 位运算解析
- UIView
- poj2010,无语的题,真的做不来,以后见到这类型再说吧,我用的堆(二分也可做)
- linux读书笔记6
- UI22_UICollectionView