B3637 最长上升子序列
代码:
#include <bits/stdc++.h>
using namespace std;
int a[5050];
int f[5050];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
//f[i]=max(f[1]+1,f[2]+1,...,f[i-1]+1)
for(int i=1;i<=n;i++)
{
f[i]=1;//初始长度为1
for(int j=1;j<i;j++)
if(a[i]>a[j]) f[i]=max(f[i],f[j]+1);//得是递增才会触发判断
}
int k=1;
for(int i=2;i<=n;i++)if(f[i]>f[k])k=i;
cout<<f[k];
return 0;
}
解析:
动态规划,从前往后判断是否上升。
P1115 最大子段和
代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[200020],b[200020],i,ans=-2147483647;
// b[i] 表示截止到 i 时,第 i 个数所在的有效序列的元素和。
int main(){
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i];
if(i==1) b[i]=a[i];
else b[i]=max(a[i],b[i-1]+a[i]);
ans=max(ans,b[i]);
}
cout<<ans;
return 0;
}
解析:
前缀和
P8707 [蓝桥杯 2020 省 AB1] 走方格
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
int n,m,f[35][35];
int main() {
cin>>n>>m;
for(ri i=1;i<=n;i++)f[i][1]=1;
for(ri j=1;j<=m;j++)f[1][j]=1;
//从起始点到第一行和第一列的方案数都为 1
for(ri i=2;i<=n;i++){
for(ri j=2;j<=m;j++){
if(i%2==0&&j%2==0)f[i][j]=0;//不能进入:将方案数赋为 0
else f[i][j]=f[i-1][j]+f[i][j-1];//能进入:计算从左和从上走到当前位置的方案数
}
}
cout<<f[n][m];//输出答案
return 0;
}
解析:
计算左和上网格步数之和
P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles
代码:
include<iostream>
include<cstdio>
include<cmath>
using namespace std;
int n;
int a[1000][1000];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
scanf("%d",&a[i][j]);//以上输入
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;j++)//for循环按顺序扫描除最后一排前的所有数
a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
//从左下,右下中选取大的加到现在的位置上
}
cout<<a[0][0]<<endl;
return 0;
}
解析:
从下往上递推
P1020 [NOIP1999 普及组] 导弹拦截
代码:
#include<bits/stdc++.h>
#define up(l,r,i) for(int i=l,END##i=r;i<=END##i;++i)
#define dn(r,l,i) for(int i=r,END##i=l;i>=END##i;--i)
using namespace std;
typedef long long i64;
const int INF =2147483647;
const int MAXN=1e5+3;
int n,t,H[MAXN],F[MAXN];
int main(){
while(~scanf("%d",&H[++n])); --n;
t=0,memset(F,0,sizeof(F)),F[0]=INF;
up(1,n,i){
int l=0,r=t+1; while(r-l>1){
int m=l+(r-l)/2;
if(F[m]>=H[i]) l=m; else r=m;
}
int x=l+1; // dp[i]
if(x>t) t=x; F[x]=H[i];
}
printf("%d\n",t);
t=0,memset(F,0,sizeof(F)),F[0]=0;
up(1,n,i){
int l=0,r=t+1; while(r-l>1){
int m=l+(r-l)/2;
if(F[m]<H[i]) l=m; else r=m;
}
int x=l+1;
if(x>t) t=x; F[x]=H[i];
}
printf("%d\n",t);
return 0;
}
解析:
同第一题