1. The longest common subsequence
1. Topic:
2. Solution:
If the i-th character of s1 is the same as the j-th character of s2, dp[i][j]=dp[i-1][j-1]+1, if different, it is equal to max(dp[i-1 ][j],dp[i][j-1])
3. ac code:
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
int main(){
char s1[200],s2[200];
int i,j;
int n1,n2;
int dp[200][200];
while(~scanf("%s%s",s1+1,s2+1)){
n1=strlen(s1+1);
n2=strlen(s2+1);
memset(dp,0,sizeof(dp));
for(i=1;i<=n1;i++){
for(j=1;j<=n2;j++){
if(s1[i]==s2[j]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
cout<<dp[n1][n2]<<endl;
}
}
2. The largest submatrix
Reference 1 (not completely correct)
Reference 2
1. Topic:
2. Solution:
See reference one
3. ac code:
Compared with reference 1, only this part has been changed:
if(sum>0)
sum+=b[k];
else
sum=b[k];//可能矩阵全负
//sum=max(b[k],sum+b[k])
original:
sum+=b[k];
if(sum<0)
sum=b[k];//可能矩阵全负
I don’t know what the original situation will get stuck, ask for advice
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
typedef long long ll;
int main(){
int n;
int a[105][105];
int i,j,k;
int b[105];
while(cin>>n){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
cin>>a[i][j];
}
}
int maxn=-9999999;
for(i=1;i<=n;i++){
memset(b,0,sizeof(b));//每次开始行变化时都需要初始化b,b表示的是从i行到j行的最大子矩阵。
for(j=i;j<=n;j++){
int sum=0;
for(k=1;k<=n;k++){
b[k]+=a[j][k];
if(sum>0)
sum+=b[k];
else
sum=b[k];//可能矩阵全负
if(sum>maxn)
maxn=sum;
}
}
}
cout<<maxn<<endl;
}
}
//101010101000000111111
There is also the most conventional method, O(n^4),
see this article for details
Three. Split Apple
1. Topic:
2. Solution:
1. Recursion:
Let f(m,n) be m apples and the number of ways to place n plates, then first discuss
n . When n>m: there must be nm plates that are always empty. Remove them. Make an impact. That is if(n>m) f(m,n) = f(m,m)
when n<=m: different placement methods can be divided into two categories:
1. At least one plate is empty, which is equivalent to f(m ,n) = f(m,n-1);
2. There are apples on all plates, which is equivalent to removing one apple from each plate without affecting the number of different placement methods, that is, f(m,n) = f(mn,n).
And the total number of ways to put apples is equal to the sum of the two, that is, f(m,n) = f(m,n-1)+f(mn,n)
recursive exit condition description:
When n=1, all apples must be placed on a plate, so return 1;
when there are no apples to put, it is defined as one method of placing;
two recursive paths, the first n will gradually decrease, and eventually Reach the exit n=1; the
second m will gradually decrease, because when n>m, we will return f(m,m), so we will eventually reach the exit m=0.
2.dp:
create a new dynamic programming table dp; dp[i][j] represents the number of ways to put j apples on i plates.
Then when i> j, dp[i][j] = dp[i-(i-j)][j] = dp[j][j]
When i <= j, dp[i][j] = dp[i-1][j] + dp[i][j-i];
Finally, dp[n][m] is what you want.
3. ac code:
#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
typedef long long ll;
int dg(int n,int m){
if(n==0||m==1)
return 1;
if(n<m)
return dg(n,n);
return dg(n-m,m)+dg(n,m-1);
}
int main(){
int n,m,t,c;
while(cin>>t){
while(t--){
cin>>n>>m;
c=dg(n,m);
cout<<c<<endl;
}
}
}