A 题目链接
编辑距离板子题

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int qs=2e5+7; 5 const int inf=0x3f3f3f3f; 6 int dp[1007][1007]; 7 char a[1007],b[1007]; 8 int main() 9 { 10 int i,j,k; 11 cin>>a+1>>b+1; 12 int l1=strlen(a+1); 13 int l2=strlen(b+1); 14 for(i=1;i<=l1;++i) 15 for(j=1;j<=l2;++j) 16 dp[i][j]=inf; 17 // dp[i][j] 表示的是在a的前i个字符,b的前j个字符的情况下最小编辑距离 18 for(i=1;i<=l1;++i) dp[i][0]=i; //初始化 19 for(j=1;j<=l2;++j) dp[0][j]=j; 20 for(i=1;i<=l1;++i) 21 { 22 for(j=1;j<=l2;++j) 23 { 24 int x; 25 int temp=min(dp[i-1][j]+1,dp[i][j-1]+1); 26 if(a[i]==b[j]) x=0; 27 else x=1; 28 dp[i][j]=min(temp,dp[i-1][j-1]+x); 29 } 30 } 31 cout<<dp[l1][l2]<<endl; 32 return 0; 33 }
B 题目链接
LCS

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int qs=2e5+7; 5 const int inf=0x3f3f3f3f; 6 int dp[1007][1007]; 7 int A[1007][1007]; 8 char a[1007],b[1007]; 9 int main() 10 { 11 int i,j,k; 12 cin>>a+1>>b+1; 13 int l1=strlen(a+1); 14 int l2=strlen(b+1); 15 for(i=1;i<=l1;++i) 16 { 17 for(j=1;j<=l2;++j) 18 { 19 if(a[i]==b[j]){ 20 dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); 21 A[i][j]=1; 22 } 23 else if(dp[i-1][j]>dp[i][j-1]){ 24 dp[i][j]=dp[i-1][j]; 25 A[i][j]=2; 26 } 27 else 28 { 29 dp[i][j]=dp[i][j-1]; 30 A[i][j]=3; 31 } 32 } 33 } 34 // printf("1111 "); 35 string s=""; 36 for(i=l1,j=l2;i>0&&j>0;) 37 { 38 if(A[i][j]==1) 39 { 40 s+=a[i]; 41 --i;--j; 42 // cout<<s<<endl; 43 } 44 else if(A[i][j]==2) --i; 45 else if(A[i][j]==3) --j; 46 } 47 reverse(s.begin(),s.end()); 48 cout<<s<<endl; 49 return 0; 50 }
E 题目传送门
思路:数不超过1e18,则k最大为36,然后循环k-2,每一次把8放进去,最后剩一个时 放4,6,9任意一个,如果放0的话特判一下1。

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int main() 5 { 6 int i,j,k; 7 cin>>k; 8 if(k>36) printf("-1 "); 9 else{ 10 string s=""; 11 while(k>1) 12 { 13 k-=2; 14 s+='8'; 15 } 16 if(k==1) s+='4'; 17 cout<<s<<endl; 18 } 19 return 0; 20 }
F 题目传送门
思路:n<=50,就嗯遍历,然后取第二大的数即可。

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int qs=2e5+7; 5 const int inf=0x3f3f3f3f; 6 ll A[qs]; 7 ll B[qs]; 8 ll C[qs]; 9 int main() 10 { 11 ll i,j,k; 12 ll n,m; 13 cin>>n>>m; 14 for(i=0;i<n;++i) cin>>A[i]; 15 for(i=0;i<m;++i) cin>>B[i]; 16 for(i=0;i<n;++i) 17 { 18 C[i]=A[i]*B[0]; 19 for(j=1;j<m;++j) 20 C[i]=max(C[i],A[i]*B[j]); 21 } 22 sort(C,C+n); 23 cout<<C[n-2]<<endl; 24 return 0; 25 }
G 题目传送门
思路:如 1 1 2 2 1 1 2 2,若要求出反转后的最长子序列,则原子序列肯定由4段组成(两段1,两段2),则用dp求出前4段最长的子序列长度

1 #include<bits/stdc++.h> 2 int dp[7]; 3 int main() 4 { 5 ll i,n,x; 6 cin>>n; 7 for(i=1;i<=n;++i) 8 { 9 cin>>x; 10 dp[1]+=(x==1); 11 dp[2]=max(dp[1],dp[2]+(x==2)); 12 dp[3]=max(dp[2],dp[3]+(x==1)); 13 dp[4]=max(dp[3],dp[4]+(x==2)); 14 } 15 cout<<dp[4]; 16 return 0; 17 }
总结:啥也不会。。。