当前位置: 首页 > 面试经验 >

关于2024-4-15拼多多笔试

优质
小牛编辑
78浏览
2024-04-15

关于2024-4-15拼多多笔试

被A弄的有点红温了,这次题解就随便写写吧

A

一眼DP 因为最多挖掉两个空格 但是只有64分

调了快一小时的DP都没出答案,有人和我说,只考虑挖第一个或最后一个,或者挖前两个,最后两个,挖最前最后过了?????

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>

#define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
using namespace std;
char s[10050];
long long dp[10050][3];
void solve(int n)
{
    scanf("%s",s+1);
    if(n<3)
    {
        printf("0 0\n");
        return;
    }
    int len=strlen(s+1);
    len=n;
    for(int i=0;i<=n+5;i++)
    {
        _for(j,0,2)
        {
            dp[i][j]=1000000000;
        }
    }
    dp[0][0]=0;
    _for(i,1,len)
    {
        _for(j,1,2) dp[i][j]=dp[i-1][j-1];
        if(i>=3)
        {
            dp[i][0]=dp[i-3][0]+abs((int)s[i-2]-'P')+abs((int)s[i-1]-'D')+abs((int)s[i]-'D');
            _for(j,1,2)
            {
                dp[i][j]=min(dp[i][j],dp[i-3][j]+abs((int)s[i-2]-'P')+abs((int)s[i-1]-'D')+abs((int)s[i]-'D'));
            }
        }
    } 
    printf("%d %lld\n",len/3,dp[len][len%3]);
}
int main(void)
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        solve(n);
    }
}
/*
6
ADDPBB
6
ADDPBB
7
ABCDEFG
7
ABCDEFG
7
ABCDEFG
6
ADDPBB
7
ABCDEFG

*/

B

由于当(a[i]==a[i+1])时,合法区间的左端点一定≥l,因此一边维护目前所有合法区间的和,一边加给更新答案即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>

#define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
using namespace std;
#define MAXN 1000050
const int mod=10000007;
int arr[MAXN];
int main(void)
{
    int n;
    scanf("%d",&n);
    int ans=0;
    int cnt=0;
    int flag=0;
    _for(i,1,n) scanf("%d",&arr[i]);
    _for(i,1,n)
    {
        if(i==1||arr[i]==arr[i-1])
        {
            cnt=0;
            flag=0;
        }
        else
        {
            ++flag;
            cnt=(cnt)+(1ll*arr[i]*flag%mod)+arr[i-1];
            cnt%=mod;
            ans+=cnt;
            ans%=mod;
        }
        // printf("%d %d\n",cnt,ans);
    }
    printf("%d",ans);
}

C

枚举第一段,计算答案并且维护即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;
#define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

#define MAXN 1050
#define pii pair<int,int>
int n;
int arr[MAXN];
pii judge(int len)
{
    int req=0;
    int wid=len;
    _for(i,1,len)
    {
        req+=arr[i];
    }
    int need,cnt;
    need=req,cnt=0;
    _for(i,len+1,n)
    {
        need-=arr[i];
        ++cnt;
        if(need<0)
        {
            return pii(n+1,-1);
        }
        if(need==0)
        {
            need=req;
            wid=max(wid,cnt);
            cnt=0;
        }
    }
    if(need!=req)
    {
        return pii(n+1,-1);
    }
    return pii(wid,req);
}
int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        _for(i,1,n) scanf("%d",&arr[i]);
        pii ans=pii(n+1,-1);
        _for(i,1,n)
        {
            ans=min(ans,judge(i));
        }
        printf("%d %d\n",ans.first,ans.second);
    }
}

D

做了个猜测,掰掉的巧克力要么取其中一块分,要么取其中一块的全部,用另一块分,由于时间紧张,没有去做数学证明,但是感觉比较合理,然后进行O(n^4)的DP即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;
#define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define MAXN 55

int dp[MAXN][MAXN][MAXN];
void solve(int n,int m,int k)
{
    // printf("solve(%d %d %d)\n",n,m,k);
    dp[n][m][k]=998244353;
    if(n*m==k||k==0)
    {
        dp[n][m][k]=0;
        return;
    }
    if(n==0||m==0)
    {
        dp[n][m][k]=-1;
        return;
    }
    int cost;
    for(int i=1;i<n;i++)
    {
        cost=m*m;
        
        if(dp[n-i][m][k]!=-1) dp[n][m][k]=min(dp[n][m][k],dp[n-i][m][k]+cost);
        if(k-m*i>=0&&dp[n-i][m][k-m*i]!=-1) dp[n][m][k]=min(dp[n][m][k],dp[n-i][m][k-m*i]+cost);
        // printf("%d of n: %d\n",i,dp[n][m][k]);
    }
    for(int i=1;i<m;i++)
    {
        cost=n*n;
        if(dp[n][m-i][k]!=-1) dp[n][m][k]=min(dp[n][m][k],dp[n][m-i][k]+cost);
        if(k-n*i>=0&&dp[n][m-i][k-n*i]!=-1) dp[n][m][k]=min(dp[n][m][k],dp[n][m-i][k-n*i]+cost);
        // printf("%d of m: %d\n",i,dp[n][m][k]);
    }
    if(dp[n][m][k]==998244353) dp[n][m][k]=-1;
}
int main(void)
{
    _for(i,0,50) _for(j,0,50) _for(k,0,50) solve(i,j,k);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        printf("%d\n",dp[x][y][z]);
    }
}

 类似资料: