zoukankan      html  css  js  c++  java
  • bzoj1566 [NOI2009]管道取珠

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1566

    十分巧妙的dp。

    关键是思考式子的意义,就能根据意义来推。

    本题a[i]^2的意义可以看做是有两个人在排序列,排出来的结果一样的方案。(思路在于“方案 * 方案”的乘法原理)

    这是10s+的代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=505;const ll mod=1024523;
    int n,m;
    char a[N],b[N];
    ll dp[2][N][N];
    int main()
    {
        scanf("%d%d ",&n,&m);
        cin>>(a+1)>>(b+1);
        dp[0][0][0]=1;
        for(int i=1;i<=n+m;i++)
        {
            memset(dp[i&1],0,sizeof dp[i&1]);
            for(int j=max(0,i-m);j<=n&&j<=i;j++)
                for(int k=max(0,i-m);k<=n&&k<=i;k++)
                {
                    if(b[m-(i-j)+1]==b[m-(i-k)+1])(dp[i&1][j][k]+=dp[(i-1)&1][j][k])%=mod;
                    if(j&&a[n-j+1]==b[m-(i-k)+1])(dp[i&1][j][k]+=dp[(i-1)&1][j-1][k])%=mod;
                    if(k&&b[m-(i-j)+1]==a[n-k+1])(dp[i&1][j][k]+=dp[(i-1)&1][j][k-1])%=mod;
                    if(j&&k&&a[n-j+1]==a[n-k+1])(dp[i&1][j][k]+=dp[(i-1)&1][j-1][k-1])%=mod;
    //              printf("dp[%d][%d][%d]=%lld
    ",i,j,k,dp[i&1][j][k]);
                }
        }
        printf("%lld",dp[(n+m)&1][n][n]);
        return 0;
    }
    View Code

    如果把字符串一开始就翻转,可以变成9s+;把 ( i & 1 ) 和 ( i - j )之类的设个变量代替,可以变成7s+;

    把long long改成int,可以变成4s+!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=505,mod=1024523;
    int n,m;
    char a[N],b[N];
    int dp[2][N][N];
    int main()
    {
        scanf("%d%d ",&n,&m);
        cin>>(a+1)>>(b+1);
        for(int i=1;i<=(n>>1);i++)swap(a[i],a[n-i+1]);
        for(int i=1;i<=(m>>1);i++)swap(b[i],b[m-i+1]);
        dp[0][0][0]=1;
        for(int i=1;i<=n+m;i++)
            for(int j=max(0,i-m);j<=n&&j<=i;j++)
                for(int k=max(0,i-m);k<=n&&k<=i;k++)
                {
                    int x=(i&1),y=!x,u=i-j,v=i-k;
                    dp[x][j][k]=0;
                    if(b[u]==b[v])(dp[x][j][k]+=dp[y][j][k])%=mod;
                    if(j&&a[j]==b[v])(dp[x][j][k]+=dp[y][j-1][k])%=mod;
                    if(k&&b[u]==a[k])(dp[x][j][k]+=dp[y][j][k-1])%=mod;
                    if(j&&k&&a[j]==a[k])(dp[x][j][k]+=dp[y][j-1][k-1])%=mod;
    //                printf("dp[%d][%d][%d]=%lld
    ",i,j,k,dp[i&1][j][k]);
                }
        printf("%d",dp[(n+m)&1][n][n]);
        return 0;
    }
  • 相关阅读:
    第四季-专题8-Linux系统调用
    第四季-专题7-Linux内核链表
    Python3 运算符
    Python2和Python3有什么区别?
    python常见的PEP8规范
    机器码和字节码
    域名是什么?为什么域名是www开头?
    selenium自动化登录qq邮箱
    xpath+selenium工具爬取腾讯招聘全球岗位需求
    ArrayList
  • 原文地址:https://www.cnblogs.com/Narh/p/9164272.html
Copyright © 2011-2022 走看看