zoukankan      html  css  js  c++  java
  • UVA 12063 Zeros and Ones(三维dp)

    题意:给你n、k,问你有多少个n为二进制的数(无前导零)的0与1一样多,且是k的倍数

    题解:对于每个k都计算一次dp,dp[i][j][kk][l]表示i位有j个1模k等于kk且第一位为l(0/1)

       再次预处理mod[i][j]表示1的i次方模j等于几,具体看代码注释

       

    import java.util.Scanner;
    
    public class Main{
        static int Maxn=65;
        static int Maxk=101;
        //前i个数有j个1模给定的值余k且第一位为1或者0的总个数
        static long[][][][] dp = new long[Maxn][Maxn][Maxk][2];
        //初始化1的i次方模j等于几
        static int[][] Mod=new int[Maxn][Maxk];
        
        //初始化
        static void Init(){
            for(int i=0;i<Maxn;++i){
                for(int j=1;j<Maxk;++j){
                    Mod[i][j]=(int) ((1L << i)%j);
                }
            }
        }
        //按位dp求出当有n位是模kk等于0的总个数
        static long Solve(int n,int kk){
            if(kk==0||(n&1)==1)//特判
                return 0L;for(int i=0;i<=n;++i)//初始化
                for(int j=0;j<=i;++j)
                    for(int k=0;k<=kk;++k){
                        dp[i][j][k][0]=dp[i][j][k][1]=0L;
                    }
            dp[0][0][0][0]=1L;
            //每种dp的i位只与i-1位相关
            for(int i=1;i<=n;++i){
                //求i位有i/2个1时需要i-1位有i/2与i/2-1个1,但是再向前推就需要更多所以将出现所有可能个1的情况求出
                for(int j=0;j<=i&&j<=n/2;++j){
                //模kk等于所有k的情况都需要求出,用于下一次使用
                    for(int k=0;k<kk;++k){
                        //此位置放0
                        dp[i][j][k][0]+=dp[i-1][j][k][0]+dp[i-1][j][k][1];
                        //此位置放1,k就等于前一个是当前位置减去(1<<i-1)后再模kk的值
                        if(j>0){
                            dp[i][j][k][1]+=dp[i-1][j-1][(k+kk-Mod[i-1][kk])%kk][0]+dp[i-1][j-1][(k+kk-Mod[i-1][kk])%kk][1];//计算余数
                        }
                        
                    }
                }
            }
            return dp[n][n/2][0][1];
        }
        public static void main(String[] args) {
            int t,coun=0;
            int n,k;
            Init();
            Scanner sc =new Scanner(System.in);
            t=sc.nextInt();
            while(t!=0){
                n=sc.nextInt();
                k=sc.nextInt();
                System.out.println("Case "+(++coun)+": "+Solve(n,k));
                t--;
            }
    
        }
    }
  • 相关阅读:
    You can’t access this shared folder because your organization’s security policies block unauthenticated guest access
    iOS 程序退出之后
    给网站得标签头加上小图标
    ios外界蓝牙适配
    JavaScript&jquery判断下载地址是否可用,同时判断浏览器是否禁用弹窗
    GCD初级使用
    find与xargs
    sed命令详解
    shell变量详解
    date命令详解
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/6701844.html
Copyright © 2011-2022 走看看