【DP】【lis】【lcs】【合并石子】【背包问题】DP基础问题四则
来源:互联网 发布:熊孩子洗琴 知乎 编辑:程序博客网 时间:2024/05/16 19:07
Re.DP复习题
1.lis 最长上升序列
输入 第一行一个整数n,第二行n个整数
输出 lis长度
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#define LL long long#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;const int maxn = 10005;int n;int dp[maxn],m[maxn];void lis(){ int maxxx = 0; for(int i = 0; i < n; ++i) { dp[i] = 1; scanf("%d", &m[i]); for(int j = 0; j < i; j++) if(m[j] < m[i]) dp[i] = max(dp[j]+1, dp[i]); maxxx = max(maxxx, dp[i]); } printf("%d",maxxx);}int main(){ scanf("%d",&n) lis(); return 0;}
2.合并石子
n 堆石子排成一圈,第i 堆石子有ai 个
每次可以合并相邻的两堆石子成一堆,代价为两堆石子的个数之和
求将n 堆石子合并成一堆的最小代价(n<=300)
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#define LL long long#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;const int maxn = 305;int f[maxn][maxn];int a[maxn],s[maxn];int n;int main(){ scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); for(int i = 1; i <= n; i++) s[i] = s[i-1] + a[i]; memset(f, 0x3f, sizeof(f)); for(int i = 1; i <= n; i++) f[i][i] = 0; for(int i = n; i >= 1; i--) for(int j = i + 1; j <= n; j++) for(int k = i; k <= j - 1; k++) f[i][j] = min(f[i][j], f[i][k]+f[k+1][j]+s[j]-s[i-1]); printf("%d\n",f[1][n]); return 0;}
3.lcs 最长公共子串
已知字符串A、B,求前缀两两之间的最长公共子串。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#define LL long long#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std; const int maxn = 3005;char a[3][maxn];int dp[maxn][maxn];int len1,len2;int main(){ for(int i = 1; i <= 2; i++) scanf("%s", a[i] + 1); len1 = strlen(a[1] + 1); len2 = strlen(a[2] + 1); for(int i = 1; i <= len1; ++i) { for(int j = 1; j <= len2; ++j) { dp[i][j] = max(dp[i][j-1], dp[i-1][j]); if(a[1][i] == a[2][j]) dp[i][j] = max(dp[i][j], dp[i-1][j-1] + 1); } } printf("%d",dp[len1][len2]); return 0;}
4.背包问题
……好多好多背包
就写个01、完全
①01背包
n 个物品,第i 个物品有体积vi,价值wi。
现在有容量为V 的背包,求可以容纳的物品的最大价值和。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#define LL long long#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std; const int maxm = 201, maxn = 31;int m,n;int w[maxn],c[maxn];int dp[maxm],f[maxn][maxm];void DP1(){ for(int i = 1; i <= n; i++) for(int v = m; v > 0; v--) if(w[i] <= v) f[i][v] = max(f[i-1][v], f[i-1][v-w[i]]+c[i]); else f[i][v] = f[i-1][v]; printf("%d\n",f[n][m]);}void DP2(){ for(int i = 1; i <= n; i++) for(int v = m; v >= w[i]; v--) if(dp[v-w[i]] + c[i] > dp[v]) dp[v] = dp[v-w[i]] + c[i]; printf("%d\n",dp[m]);}int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) scanf("%d%d",c[i],w[i]); DP1(); //一维数组 DP2(); //二维数组 return 0;}
②完全背包
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#define LL long long#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std; const int maxm = 201, maxn = 31;int m,n;int w[maxn],c[maxn];int dp[maxm],f[maxn][maxm];void DP1(){ for(int i = 1; i <= n; i++) for(int v = 1; v <= m; v++) if(v < w[i]) f[i][v] = f[i-1][v]; else f[i][v] = max(f[i-1][v],f[i][v-w[i]]+c[i]);}void DP2(){ for(int i = 1; i <= n; i++) for(int v = w[i]; v <= m; v++) if(dp[v-w[i]]+c[i] > dp[v]) dp[v] = dp[v-w[i]]+c[i]; printf("%d\n",dp[m]);}int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) scanf("%d%d",c[i],w[i]); DP1(); //一维数组 DP2(); //二维数组 return 0;}
0 0
- 【DP】【lis】【lcs】【合并石子】【背包问题】DP基础问题四则
- 【dp】石子合并问题
- dp 石子合并问题
- 石子合并问题(dp)
- ACM DP 石子合并问题
- 环形石子合并问题 - 经典DP问题
- NKOJ 1137 石子合并问题 (区间dp)
- 经典问题石子合并(环形)DP
- 石子合并问题 (区间dp)
- 石子合并问题(区间DP)
- ssl1597-石子合并问题【区间dp练习】
- 石子合并~区间dp基础
- Dp基础 简单背包问题
- DP-LIS问题
- SDUTOJ. LCS问题.(DP)
- hrbust1818 石子合并问题--直线版 (经典区间DP)
- 石子合并问题 (朴素区间DP&&GarsiaWachs算法)
- Hrbust 1818 石子合并问题--直线版【区间dp】
- GitHub入门与实践学习笔记--github学习基础之关于git的基本操作
- Android TextView disable颜色坑
- 文章标题
- windosw下安装matplotlib之痛
- UILabel根据内容获取宽高
- 【DP】【lis】【lcs】【合并石子】【背包问题】DP基础问题四则
- mybatis 一对一关系取值association 通过resultMap实现
- 如何给openstack虚拟机配置静态IP
- 数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
- 常见算法:C语言求最小公倍数和最大公约数的算法
- 讯飞语音识别之微信语音arm文件转换wav文件
- java 中String , StringBuilder , StringBuffer的一些比较
- 快速幂取模
- 软考总结