PAT刷题之动态规划专题
Posted 辛勤的小码农^-^
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT刷题之动态规划专题相关的知识,希望对你有一定的参考价值。
PAT刷题之动态规划专题
1. 最大连续字段和 | 11.4
1.1模板
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10010;
int A[maxn],dp[maxn]; //A[i]存放序列,dp[i]以A[i]为结尾的连续序列的
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&A[i]);
}
//边界
dp[0]=A[0];
for(int i=1;i<n;i++){
dp[i]=max(A[i],dp[i-1]+A[i]);
}
int k=0;
for(int i=0;i<n;i++){
if(dp[i]>dp[k]){
k=i;
}
}
printf("%d\\n",dp[k]);
return 0;
}
//6
//-2 11 -4 13 -5 -2
//20
1.2 A1007 最大连续字段和
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10010;
int A[maxn],dp[maxn]; //A[i]存放序列,dp[i]以A[i]为结尾的连续序列的最大和
int s[maxn]={0}; //s[i]表示 产生dp[i]的连续序列从a的哪一个元素开始
int main(){
int n;
bool flag=false; //flag表示数组a中是否全小于0
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&A[i]);
if(A[i]>=0) flag=true;
}
if(flag==false){
printf("0 %d %d\\n",A[0],A[n-1]);
}
//边界
dp[0]=A[0];
for(int i=1;i<n;i++){
if(A[i]<dp[i-1]+A[i]){ //输出ij最小的方案,故此情况的优先级更高
dp[i]=dp[i-1]+A[i];
s[i]=s[i-1];
}else{
dp[i]=A[i];
s[i]=i;
}
}
int k=0;
for(int i=0;i<n;i++){
if(dp[i]>dp[k]){
k=i;
}
}
printf("%d %d %d\\n",dp[k],A[s[k]],A[k]);
return 0;
}
/*10
-10 1 2 3 4 -5 -23 3 7 -21
10 1 4
*/
2. 最长不下降子序列 | 11.3
2.1 LIS模板
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100;
int A[maxn],dp[maxn]; //以A[i]结尾的最长不下降子序列
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&A[i]);
}
int ans=-1;
for(int i=1;i<=n;i++){
dp[i]=1;
for(int j=1;j<i;j++){
if(A[i]>=A[j]&&(dp[j]+1>dp[i])){
dp[i]=dp[j]+1;
}
}
ans=max(ans,dp[i]);
}
printf("%d",ans);
return 0;
}
/*
8
1 2 3 -9 3 9 0 11
5
*/
2.3 A1045最喜欢的颜色条(LIS)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxc=210; //最大颜色数
const int maxn=10010; //最大L
int HashTable[maxc]; //将喜欢的颜色序列映射为递增序列,不喜欢的颜色映射为1
int A[maxn],dp[maxn]; //原数组和DP数组
int main()
{
int n,m,x;
scanf("%d",&m);
memset(HashTable,-1,sizeof(HashTable));//整个数组初始化为-1
for(int i=0;i<m;i++){
scanf("%d",&x);
HashTable[x]=i; //将喜欢的颜色映射到递增序列
}
int L,num=0;
scanf("%d",&L);
for(int i=0;i<L;i++){
scanf("%d",&x);
if(HashTable[x]>=0){
A[num++]=HashTable[x];
}
}
//LIS模板
int ans=-1;
for(int i=0;i<num;i++){
dp[i]=1;
for(int j=0;j<i;j++){
if(A[i]>=A[j]&&dp[j]+1>dp[i])
dp[i]=dp[j]+1;
}
ans=max(ans,dp[i]);
}
printf("%d",ans);
return 0;
}
/*
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
7
*/
3. 最长公共子序列(LCS)|11.4
3.1 模板
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=200;
char A[N],B[N];
int dp[N][N]; //A的i号位和B的j号位之前的LCS长度(下标从1开始)
int main(){
int n;
gets(A+1);
gets(B+1);
int lenA=strlen(A+1);
int lenB=strlen(B+1);
for(int i=0;i<=lenA;i++){
dp[i][0]=0;
}
for(int i=0;i<=lenB;i++){
dp[0][i]=0;
}
//状态转移方程
for(int i=1;i<=lenA;i++){
for(int j=1;j<=lenB;j++){
if(A[i]==B[j]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
printf("%d\\n",dp[lenA][lenB]);
return 0;
}
/*
sadstory
adminsorry
6
*/
3.2 A1045最喜欢的颜色条(LCS)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxc=210; //最大颜色数n
const int maxn=10010; //最大m
int A[maxc],B[maxn],dp[maxc][maxn]; //原数组和DP数组
int main(){
int m,n;
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%d",&A[i]);
}
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&B[i]);
}
for(int i=0;i<=m;i++){
dp[i][0]=0;
}
for(int i=0;i<=n;i++){
dp[0][i]=0;
}
//状态转移方程
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(A[i]==B[j]){ //允许重复值的出现
dp[i][j]=max(dp[i-1][j],dp[i][j-1])+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
printf("%d\\n",dp[m][n]);
return 0;
}
/*
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
7
*/
以上是关于PAT刷题之动态规划专题的主要内容,如果未能解决你的问题,请参考以下文章