/* 1)动态规划的基本思想:将复杂问题进行分解简化,通过去求解
小规模子问题反推出原问题的结果。动态规划适合求解多阶
段决策问题的最优解(可以简单理解为有状态转换的阶段性
问题)。这些问题必须满足最优化原理和子问题的无后向性。
2)两个要素:最优子结构性质和子问题重叠性质。
1.最优子结构:
如果问题的最优解所包含的子问题的解也是最优的,
我们就称该问题具有最优子结构性质(即满足最优化原
理)。意思就是,总问题包含很多个子问题,而这些子
问题的解也是最优的。
2.重叠子问题:
子问题重叠性质是指在用递归算法自顶向下对问题
进行求解时,每次产生的子问题并不总是新问题,有些
子问题会被重复计算多次。动态规划算法正是利用了这
种子问题的重叠性质,对每一个子问题只计算一次,然
后将其计算结果保存在一个表格中,当再次需要计算已
经计算过的子问题时,只是在表格中简单地查看一下结
果,从而获得较高的效率。
3)动态规划算法的基本步骤:
1.将原问题分解为子问题(子问题和原问题形式相同,且子问题解求出就会被保存);
2.确定状态:比如在01背包中一个状态就是个物体中第个是否放入体积为背包中;
3.确定一些初始状态(边界状态)的值;
4.确定状态转移方程,如何从一个或多个已知状态求出另一个未知状态的值。(递推型)*/
/*最长公共子序列(longest common sequence)和最长
公共子串(longest common substring)不一样子序列:
即一个给定的序列的子序列,就是将给定序列中零个或
多个元素去掉之后得到的结果子串:给定串中任意个连续
的字符组成的子序列称为该串的子串*/
/*lcs
#include <iostream>
#include <cstring>
using namespace std;
#define NUM 1010
int c[NUM][NUM];
int b[NUM][NUM];
void LCS_LENGTH(string X, string Y);
void PRINT_LCS(string X,int m, int n);
int main()
{
string X, Y;
cin >> X >> Y;
LCS_LENGTH(X, Y);
PRINT_LCS(X,X.length(), Y.length());
return 0;
}
void LCS_LENGTH(string X, string Y)
{
int m = X.length();
int n = Y.length();
for (int i = 0; i <= m; i++)
c[i][0] = 0;
for (int j = 0; j <= n; j++)
c[0][j] = 0;
for (int i = 1; i <= m; i++){
for (int j = 1; j <= n; j++){
if (X[i - 1] == Y[j - 1]){
c[i][j] = c[i - 1][j - 1] + 1;
b[i][j] = 1;
}
else if (c[i - 1][j] >= c[i][j - 1]){
c[i][j] = c[i - 1][j];
b[i][j] = 2;
}
else{
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
}
void PRINT_LCS(string X,int m, int n)
{
if (m == 0 || n == 0)
return;
if (b[m][n] == 1){
PRINT_LCS(X,m - 1, n - 1);
cout << X[m-1];
}
else if (b[m][n] == 2){
PRINT_LCS(X, m - 1, n);
}
else
PRINT_LCS(X, m, n - 1);
}*/
//背包问题
/*#include <iostream>
using namespace std;
#define m 10010
int v[110][m]={0};
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,w,i,j;
cin>>n>>w;
int a[n+1],b[n+1];
for(i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
for(i=0;i<=n;i++)
{
v[i][0]=0;
}
for(j=0;j<=w;j++)
{
v[0][j]=0;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=w;j++)
{
if(j<a[i]) v[i][j]=v[i-1][j];
else v[i][j]=max(v[i-1][j],v[i-1][j-a[i]]+b[i]);
}
}
int mmm=0;
for(i=0;i<=n;i++)
{
for(j=0;j<=w;j++)
{
if(v[i][j]>=mmm)
{
mmm=v[i][j];
}
}
}
cout<<mmm<<endl;
return 0;
}*/
/*数字三角形
记忆化搜索
#include <iostream>
#include <algorithm>
using namespace std;
#define m 1000
int n;
int a[m][m];
int b[m][m];
int solve(int i,int j);
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<=i;j++)
{
cin>>a[i][j];
b[i][j]=-1;
}
}
int z=solve(0,0);
cout<<z<<endl;
return 0;
}
int solve(int i,int j)
{
if(b[i][j]!=-1) return b[i][j];
if(i==n-1) return b[i][j]=a[i][j]+0;
return b[i][j]=a[i][j]+max(solve(i+1,j),solve(i+1,j+1));
}*/
/*递推
int i,j;
for(int j=0;j<n;j++)
{
b[n-1][j]=a[n-1][j];
}
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;j++)
{
b[i][j]=max(b[i+1][j],b[i+1][j+1]);
}
}*/
/*#include <iostream>
#include <algorithm>
using namespace std;
#define m 10010
int t,i,j,n;
struct jx
{
int x,y;
}a[m];
int b[m][m]={0},c[m]={0};
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i].x>>a[i].y;
if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i].x>a[j].x&&a[i].y>a[j].y) b[i][j]=1;
}
}
for(i=0;i<n;i++)
{
}
}
}
int dpdag(int i)
{
if(c[i]>0) return c[i];
c[i]=1;
for(j=0;j<n;j++)
{
if(b[i][j]==1) c[m]=c[m]>dpdag(j)+1?c[m]:dpdag(j)+1;
}
return b[i];
}*/
/*最大字段和
#include <iostream>
using namespace std;
int main()
{
int n,i;
cin>>n;
int a[n];
long long int b[n],max=0;
for(i=0;i<n;i++)
{
cin>>a[i];
}
b[0]=a[0];
for(i=1;i<n;i++)
{
if(b[i-1]>0)
b[i]=b[i-1]+a[i];
else b[i]=a[i];
if(b[i]>max)
max=b[i];
}
cout<<max<<endl;
return 0;
}*/
/*P1060 开心的金明
#include <iostream>
#include <cstring>
using namespace std;
int a[30][30000+10];
int maxn(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,m;
cin>>n>>m;
int q[m+1]={0},z[m+1]={0};
for(int i=1;i<=m;i++)
cin>>q[i]>>z[i];
memset(a,0,sizeof(a));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(j<q[i]) a[i][j]=a[i-1][j];
else a[i][j]=maxn(a[i-1][j],a[i-1][j-q[i]]+q[i]*z[i]);
}
}
cout<<a[m][n]<<endl;
return 0;
}*/
动态规划
最新推荐文章于 2022-04-08 19:28:15 发布