您的位置:首页 > 其它

【dp基础课程】矩阵取数问题+最大子段和+最长公共子序列(LCS)【51nod】

2016-05-21 02:58 591 查看
原题链接:http://www.51nod.com/tutorial/index.html#!tutorialId=1

矩阵取数问题

一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价

输入

第1行:N,N为矩阵的大小。(2 <= N <= 500)

第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N[i] <= 10000)

输出

输出能够获得的最大价值。

输入示例

3

1 3 3

2 1 3

2 2 1

输出示例

11

请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
//dp矩阵取数问题;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int a[505][505];
int dp[505][505];   //  到x,y点的最大奖励;
int n;
cin.sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a[i][j];
memset(dp,0,sizeof(dp));
dp[0][0]=a[0][0];
for(int i=1;i<n;i++)
dp[0][i]=dp[0][i-1]+a[0][i];
for(int i=1;i<n;i++)
dp[i][0]=dp[i-1][0]+a[i][0];
for(int i=1;i<n;i++){
for(int j=1;j<n;j++){
dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j];
}
}
cout<<dp[n-1][n-1]<<endl;
return 0;
}

最大子段和

输入

第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)


输出

输出最大子段和。


输入示例

6
-2
11
-4
13
-5
-2


输出示例

20


//最大子段和
#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
int main()
{
int n;
int a[51010];
cin.sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
LL maxSum=0;
LL ans=0;
int s=0,ss=0,ee=0;    //  分别表示起始和终止位置;
for(int i=0;i<n;i++){
if(maxSum>0){   //  大于,就可以一直加;
maxSum+=a[i];
}else{
s=i;            //  标记起始位置
maxSum=a[i];    //  重新开始;
}
if(maxSum>ans){     //  判断是否能够更新ans;
ans=maxSum;
ss=s;
ee=i;
}
}
//cout<<ss<<' '<<ee<<endl;  //分别记录起始位置和终止位置;
cout<<ans<<endl;
return 0;
}

最长公共子序列_记录子序列

输入

第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)


输出

输出最长的子序列,如果有多个,随意输出1个。


输入示例

abcicba
abdkscab


输出示例

abca


/*最长公共子序列
记录序列;
*/
#include<iostream>
using namespace std;
int dp[1010][1010]={0};
int s[1010][1010]={0};       //  记录结果;
string s1,s2;
void print(int i,int j)
{
if(i==0||j==0) return;
if(s[i][j]==0){     //  相同情况;
print(i-1,j-1);
cout<<s1[i];
}
else if(s[i][j]==1)
print(i-1,j);
else
print(i,j-1);
}
int main()
{
cin.sync_with_stdio(false);
cin>>s1>>s2;
s1="#"+s1;
s2="@"+s2;
int len1=s1.size();
int len2=s2.size();
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(i==0||j==0){
dp[i][j]=0;
s[i][j]=0;
}else{
if(s1[i]==s2[j]){
dp[i][j]=dp[i-1][j-1]+1;
s[i][j]=0;
}else{
if(dp[i-1][j]>=dp[i][j-1]){
dp[i][j]=dp[i-1][j];
s[i][j]=1;
}else{
dp[i][j]=dp[i][j-1];
s[i][j]=-1;
}
}
}
}
}
print(len1-1,len2-1);
//cout<<dp[len1-1][len2-1]<<endl;
//cout<<s[len1-1][len2-1]<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: