• KEYENCE Programming Contest 2021


    AB

    签到

    C

    大力DP,f[i][j]表示走到当前位置的方案数,但问题是无法考虑没走过路径的未填位置。不过很好解决,向右走的时候实际方案=原方案数*3^(走过的列下侧的未填位置数),向下走的时候实际方案=原方案数*3^(走过的行右侧的未填位置数),这样可以处理掉所有的未填位置。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5005,mod=998244353;
    int n,m,k,pw[N],a[N][N],f[N][N],s[N][N],t[N][N];
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=-1;
        pw[0]=1;for(int i=1;i<=5000;i++)pw[i]=3ll*pw[i-1]%mod;
        for(int i=1,x,y;i<=k;i++)
        {
            char c;scanf("%d%d %c",&x,&y,&c);
            if(c=='X')a[x][y]=0;
            else if(c=='R')a[x][y]=1;
            else a[x][y]=2;
        }
        for(int j=1;j<=m;j++)
        {
            for(int i=n;i;i--)s[i][j]=s[i+1][j]+(a[i][j]==-1);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=m;j;j--)t[i][j]=t[i][j+1]+(a[i][j]==-1);
        }
        f[1][1]=1;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(j>1)
            {
                if(!a[i][j-1]||a[i][j-1]==1)f[i][j]=(f[i][j]+1ll*f[i][j-1]*pw[s[i+1][j-1]])%mod;
                else if(a[i][j-1]==-1)f[i][j]=(f[i][j]+2ll*f[i][j-1]*pw[s[i+1][j-1]])%mod;
            }
            if(i>1)
            {
                if(!a[i-1][j]||a[i-1][j]==2)f[i][j]=(f[i][j]+1ll*f[i-1][j]*pw[t[i-1][j+1]])%mod;
                else if(a[i-1][j]==-1)f[i][j]=(f[i][j]+2ll*f[i-1][j]*pw[t[i-1][j+1]])%mod;
            }
        }
        if(a[n][m]==-1)f[n][m]=3ll*f[n][m]%mod;
        printf("%d",f[n][m]);
    }
    View Code

    D

    构造能力堪忧于是成功垫底……

    很容易发现答案是2^n-1,但就是不会构造……

    发现可以将2^(n-1)个人时的答案进行如下复制,假设一个答案是A,则可以复制成AA,AB,其中B与A完全不同,再加上A…AB…B就可达到目的

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int main()
    {
        scanf("%d",&n);
        printf("%d
    ",(1<<n)-1);
        vector<string>a;
        for(int i=1;i<=n;i++)
        {
            vector<string>vec;
            string x="";
            for(int j=1;j<=(1<<i-1);j++)x+='A';
            for(int j=1;j<=(1<<i-1);j++)x+='B';
            vec.push_back(x);
            for(int j=0;j<a.size();j++)
            {
                vec.push_back(a[j]+a[j]);
                string s=a[j];
                for(int k=0;k<s.size();k++)s[k]=s[k]=='A'?'B':'A';
                vec.push_back(a[j]+s);
            }
            a=vec;
        }
        for(int i=0;i<a.size();i++)cout<<a[i]<<endl;
    }
    View Code

    E

    考完发现实际上就是DP,f[i][j][k]表示在区间[i,j],取了k个区间外的数的最大值,也是直接DP就行了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=405;
    int n,a[N],f[N][N][N];
    int dp(int l,int r,int m)
    {
        int&ret=f[l][r][m];
        if(ret)return ret;
        int t=0;
        if(l>0||r<=n)
        {
            if(m<n-(r-l-1))
            {
                if(a[l]<a[r])t=max(t,dp(l,r+1,m+1));
                else t=max(t,dp(l-1,r,m+1));
            }
            if(m>=1&&l>=1)t=max(t,a[l]+dp(l-1,r,m-1));
            if(m>=1&&r<=n)t=max(t,a[r]+dp(l,r+1,m-1));
        }
        ret=t;
        return ret;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        a[0]=a[n+1]=-1;
        for(int i=0;i<=n;i++)cout<<dp(i,i+1,1)<<endl;
    }
    View Code

    小号打的 rank=426 performance=1931 rating+=149

  • 相关阅读:
    XPOSED优秀模块列表 Xposed GEL 设置
    XPOSED优秀模块列表 Eggster
    XPOSED优秀模块列表 全部成为F
    XPOSED优秀模块列表 XBridge
    XPOSED优秀模块列表 xBoon
    XPOSED优秀模块列表 定位注入器
    showModalDialog()、showModelessDialog()方法使用详解
    手工更改数据库字符集
    blog开张了
    SQLSERVER 2008 复制之旅
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/14287817.html
Copyright © 2020-2023  润新知