• HDU 5389 Zero Escape (MUT#8 dp优化)


    【题目链接】:click here~~

    【题目大意】:

    题意:

    给出n个人的id,有两个门,每一个门有一个标号,我们记作a和b,如今我们要将n个人分成两组,进入两个门中,使得两部分人的标号的和(迭代的求。直至变成一位数,我们姑且叫做求“和”操作~)各自等于a和b,问有多少种分法。

    【思路】:比赛的时候还是学弟递推的方程。当时是dp三维dp[i][j]k]:分别表示枚举到第i位,A门。B门的状态,可是一直没想到怎么进一步优化,卡在100n的复杂度了

    赛后看了一下题解,(尽管高中生写的题解看了好像也没什么卵用~~)发现事实上能够用二维数组解决啊,仅仅要计算全部读入数组的和,和A。B门的比較一下。相等是时候进一步枚举j,否则直接推断和A,B门相等的情况,ans++,最后答案就是ans了,还是太弱了。加油吧!T_T!

    代码:

    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <stack>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <cmath>
    #define eps 0.00000001
    #define pi acos(-1,0)
    #define pr 999983
    using namespace std;
    typedef long long LL;
    const int MOD=258280327;
    int  arr[110000]= {0};
    int dp[110000][10]= {0};
    
    inline LL read()
    {
        int c=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        return c*f;
    }
    
    LL get(LL n){return (n-1)%9+1;}
    
    int main(){
        LL t,n,A,B;
        t=read();
        while(t--){
            LL sum=0;
            LL ans=0;
            memset(dp,0,sizeof(dp));
            memset(arr,0,sizeof(arr));
            n=read();A=read();B=read();
            for(int i=1; i<=n; ++i){ /// get the sum of arr[i]
                arr[i]=read();
                arr[i]=get(arr[i]);
                sum+=arr[i];
            }
            sum=get(sum);
            LL xx=get(A+B); /// judge the sum and xx
            if(sum==xx){
                dp[1][arr[1]]=1; /// dp[i][j]: 枚举到第i位和为j的方案数
                for(int i=2; i<=n; ++i){
                    for(int j=1; j<=9; ++j){
                        int k=j-arr[i];
                        if(k<=0) k+=9;
                        dp[i][j]=(dp[i-1][k]+dp[i-1][j])%MOD;
                    }
                }
                ans=(dp[n][A]+dp[n][B])%MOD;
                printf("%lld
    ",ans);
            }
            else{
                if(sum==A) ans++;
                if(sum==B) ans++;
                printf("%lld
    ",ans%MOD);
            }
        } return 0;
    }
    
    /*
    Sample Input
    4
    3 9 1
    1 2 6
    3 9 1
    2 3 3
    5 2 3
    1 1 1 1 1
    9 9 9
    1 2 3 4 5 6 7 8 9
    Sample Output
    1
    0
    10
    60
    */


  • 相关阅读:
    Docker学习(一)
    mysql定时任务
    如何查看电脑是几核的?
    卸载Mysql connect 6.9.9
    找不到该项目怎么删除
    jmeter录制app脚本
    postman使用
    排查linux系统是否被入侵
    部署apache-tomcat环境
    sudo初级授权设置
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7003058.html
Copyright © 2020-2023  润新知