【题目】
【题解】
题意:输出从下往上走的最大和。
思路:最后一行dp[i][j]=a[i][j]
状态转移方程:dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1])
【代码】
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
main()
{
int n,a[105][105],dp[105][105];
cin>>n;
go(i,1,n)
{
go(j,1,i) cin>>a[i][j];
}
og(i,n,1)
{
go(j,1,i)
{
if(i==n) dp[i][j]=a[i][j];
else dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
}
}
cout<<dp[1][1]<<endl;
}
【题目】
【题解】
题意:输出从左上角到右下角所能得到的最大和。
思路:初始位置dp[i][j]=a[i][j],dp[][]要初始化为最小值。
状态转移方程:dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i][j-1])
【代码】
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
main()
{
int n,m,a[105][105],dp[105][105];
int t; scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
go(i,1,n)
{
go(j,1,m) scanf("%d",&a[i][j]);
}
go(i,0,n)
{
go(j,0,m) dp[i][j]=-inf;
}
go(i,1,n)
{
go(j,1,m)
{
if(i==1&&j==1) dp[i][j]=a[i][j];
else dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",dp[n][m]);
}
}
【题目】
【题解】
思路:每次求以第i个数为终点的最长上升子序列的长度,然后更新答案。
状态转移方程:dp[i]=max(dp[i],dp[j]+1)
【代码】
//朴素dp O(n^2)
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
main()
{
int n,a[1005],dp[1005];
cin>>n; int ans=0;
go(i,1,n) cin>>a[i],dp[i]=1;
go(i,1,n)
{
go(j,1,i) if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
}
//贪心+二分 O(nlogn)
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
main()
{
int n,a[1005],dp[1005];
cin>>n;
go(i,1,n) cin>>a[i];
int l=1;dp[1]=a[1];
go(i,1,n)
{
if(a[i]>dp[l]) dp[++l]=a[i];
else
{
int t=upper_bound(dp+1,dp+l+1,a[i])-dp;
dp[t]=a[i];
}
}
cout<<l<<endl;
}
【题目】
【代码】
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define mem(a) memset(a,0,sizeof(a))
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
int dp[1005][1005];
main()
{
string a,b;
while(cin>>a>>b)
{
mem(dp);
int l1=a.size(),l2=b.size();
go(i,1,l1)
{
go(j,1,l2)
{
//状态转移方程
if(a[i-1]==b[j-1]) 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[l1][l2]);
}
}