动态规划一一线性动态规划
先说一下对动态规划的理解:这是一种针对段阶段问题的最优化问题的一种解法。具有最优子结构性质,局部最优与整体最优。具有子问题重叠特征,动态规划通过对子问题运行与否的记录,减少了运行次数。
动态规划实质是:记忆化搜索。
基本解题步骤:、1.分析问题的最优解,找出最优解的性质,并刻画其结构特征;
2、递归地定义最优值;
3、采用自底向上的方式计算问题的最优值;
4、根据计算最优值时得到的信息,构造最优解。
一。最长公共子序列问题。
最长公共子序列:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。求任意两个数列的最长公共走序列。
基本思路:引进二维数组记录x[i]与y[i]的lcs长度。
递归关系:c[i][j]=0, i=0,j=0;
c[i][j]=c[i-][j-1]+1; i,j>0,x[i]=y[i];
c[i][j]=max(c[i][j-1],c[i-1][j]) i,j>0,x[i]!=y[i];
代码:
#include<iostream>
#include<cstring>
using namespace std;
int longest (char a[],char b[],int m,int n);
int main()
{
int n,m,p,q;char a[10000],b[10000];
cin>>n;
while(n--)
{
cin>>a>>b;
p=strlen(a);q=strlen(b);
m=longest(a,b,q,p);
cout<<m<<endl;
}
return 0;
}
int longest (char a[],char b[],int m,int n)
{int s[100][100],i,j;
for(i=0;i<=n;i++)
s[i][0]=0;
for(j=1;j<=m;j++)
s[0][j]=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{if(a[i-1]==b[j-1])
s[i][j]=s[i-1][j-1]+1;
else
{if(s[i-1][j]>=s[i][j-1])
s[i][j]=s[i-1][j];
else
s[i][j]=s[i][j-1];
}
}
return s[n][m];
}
二。
最大字段和
给定n个整数(可能有负数)组成的数列,钻出相邻子段使其和最大,输出最大和,并确定子段数列。
#define num 1001
int a[num];
int max(int n,unt&besti,int&bestj)
{
int sum=0,b=0,begin=0;
for(int i=1;i<=n;i++)
{if(b>0) b+=a[i];
else {b=a[i];begin=i}
if(b>sum) {sum=b;besti=begin;bestj=i;}
}
return sum;
}
三。
数字三角形
从顶点出发在节点处选择向左或向右,一直到最底层,使其经过的数字和最大。
例题。cows bowling:
7Then the other cows traverse the triangle starting from its tip and moving "down" to one of the two diagonally adjacent cows until the "bottom" row is reached. The cow's score is the sum of the numbers of the cows visited along the way. The cow with the highest score wins that frame.
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Given a triangle with N (1 <= N <= 350) rows, determine the highest possible sum achievable.
Lines 2..N+1: Line i+1 contains i space-separated integers that represent row i of the triangle.
#include<iostream>
using namespace std;
int tri[100][100];
int triangle(int n)
{
int i,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
{
if(tri[i+1][j]>tri[i+1][j+1])
tri[i][j]+=tri[i+1][j];
else tri[i][j]+=tri[i+1][j+1];
}
return tri[0][0];
}
int main()
{
int n,i,j;
cin>>n;
for(i=0;i<n;i++)
for(j=0;j<i+1;j++)
cin>>tri[i][j];
cout<<triangle(n)<<endl;
return 0;
}
四。
最长不下降序列。
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
代码:
#include<iostream>
#include<cstring>
using namespace std;
int a[1002];
int longest(int n)
{
int b[1002],i,j;
for(i=1;i<=n;i++)
b[i]=1;
int max=0;
for(i=2;i<=n;i++)
{int k=0;
for(j=1;j<i;j++)
if(a[i]>a[j]&&k<b[j])
{k=b[j];
b[i]=k+1;}
if(max<b[i])
max=b[i];
}
return max;
}
int main()
{
int n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
if(a[i]<0||a[i]>10000) return 0;
if(n==1) cout<<1<<endl;
else
cout<<longest(n)<<endl;
return 0;
}