牛客假日团队赛18(A水,D水,L(四位dp))

mac2024-01-27  21

这场好难啊,写了一大节课只写出两个水题,补题也只补L题的dp题。。

G和F贪心全想错了,wa到自闭

G区间dp,F要结合二分图+栈,dp预处理

以后有时间再补吧

A-火柴棒等式

预处理一下所有的等式就可以了

#include<bits/stdc++.h> using namespace std; int a[12]={6,2,5,5,4,5,6,3,7,6}; int vis[100]; int cal(int x) { if(x==0) return a[0]; int ans=0; while(x) { int d=x%10; x=x/10; ans+=a[d]; } return ans; } int main() { int n; cin>>n; if(n<=4){ printf("0\n"); return 0; } int ans=0; //n-=4; for(int i=0;i<=1000;++i) { for(int j=0;j<=1000;++j) { int d=i+j; int t=cal(i)+cal(j)+cal(d)+4; //if(t==18) printf("%d + %d = %d\n",i,j,d); if(t>50) continue; vis[t]++; } } printf("%d\n",vis[n]); }

D-Adding Commas

按照题意写就可以了。。

#include<bits/stdc++.h> using namespace std; string s; int main() { cin>>s; stack<char>sta; int num=0; for(int i=s.size()-1;i>=0;--i) { if(num==3) num=0,sta.push(','); sta.push(s[i]); ++num; } while(sta.size()) { printf("%c",sta.top()); sta.pop(); } }

L-传纸条

题解来自:https://blog.csdn.net/belous_zxy/article/details/80530111

同时求得两条路线的数值之和最大,还要求不能走重复路线,好像很棘手……得想个办法来存储纸条每种行进可能的好心度之和,从左上到右下再回来可以看作是从左上通过两条路线到达右下,那么说表示当前状态就得表示第一个纸条的位置和第二个纸条的位置,各需要x坐标和y坐标。定义一个四维数组来表示,dp[x1][y1][x2][y2] x1,y1表示第一个纸条;x2,y2表示第二个纸条。数组里存储的就是两个纸条当前状态下最大好心度。

        然后枚举每个可能的x1、y1、x2、y2计算对应的 dp[x1][y1][x2][y2] ,状态转移方程就是当前两个位置的好心度之和加上可以到达现在位置的历史最大值!dp[x1][y1][x2][y2]=Max( dp[x1-1][y1][x2-1][y2],dp[x1-1][y1][x2][y2-1],dp[x1][y1-1][x2-1][y2],dp[x1][y1-1][x2][y2-1] )+a[x1][y1]+a[x2][y2] 。枚举时候需要注意两个点的坐标不可以相同,因为这种位置状态不可能出现。最后输出的结果可以是 dp[m][n-1][m-1][n]或dp[m-1][n][m][n-1] ,因为这两个位置到终点都是一次传递,而且好心度不会增加,他们的值是相等的。

#include<bits/stdc++.h> using namespace std; #define N 105 int a[N][N]; int dp[N][N][N][N]; int Max(int a,int b,int c,int d) { int re=a; if(b>re)re=b; if(c>re)re=c; if(d>re)re=d; return re; } int main() { int m,n; scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) for (int k=1;k<=m;k++) for (int l=1;l<=n;l++) { if((i==k&&j==l)) continue; dp[i][j][k][l]=Max(dp[i][j-1][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k][l-1],dp[i-1][j][k-1][l])+a[i][j]+a[k][l]; } printf("%d\n",dp[m][n-1][m-1][n]); return 0; }

 

最新回复(0)