zoukankan      html  css  js  c++  java
  • Ural 1057. Amount of Degrees(数位DP)

    第二次做数位DP,做了好几个小时,我先哭一会 = =

    hdu2089做法相似,不过细节要多考虑。

    首先一个数如果为B的次方和,那么用B进制表示,符合要求的数一定是一串只有0和1的数字,并且1的个数为k。

    dp[i][j] 表示i位数,首位为j的符合要求的数有多少个。

    递推公式dp[i][j]=dp[i-1][j]+dp[i-1][j-1]。(第i位为0或为1)

    利用dp对于一个N求[0,N)之间符合要求的数。

    先把一个数化为B进制,长度为len;

    对于某一位,如果该位的数字大于1,那么直接求dp[i-1][k]+dp[i-1][k-1]就是结果。

    对于某一位如果为1,那么要加上该位为0的情况,dp[i-1][k-1]

    如果为0,那么没有贡献,继续求下一位。

    记录cnt为1的个数。

    例如一个数4131(已化为b进制)

    第一位是4,那么dp[3][k]+dp[3][k-1]就是结果

    例如一个数1010

    第一位为1,那么第一位为0的所有数都小于1014,求出dp[3][k],即0xxx中满足条件的数。

    继续求1xxx中满足条件的数,因为已经确定一个数为1,这时求得的数中只需有k-1个1就可以了。

    第二位0,继续。

    第三位1,那么求第三位为0的,求100x,即dp[1][k-1]。

    然后求101x,要有k-2个1.

    最后一位0,结束。

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    // 1≤X≤Y≤2^31−1  1≤K≤20 2≤B≤10
    int x, y;
    int k, b; // b进制 k个1
    
    int dp[40][40]; // dp[i][j] i位数,一共有j个1,有多少种可能情况
    // dp[i][j]=dp[i-1][j]+dp[i-1][j-1] --第i位可能为0或1
    int d[40];
    
    void init()
    {
    	dp[0][0] = 1;
    	for (int i = 1; i <= 31; ++i) {
    		for (int j = 0; j <= 31; ++j) {
    			dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
    		}
    	}
    }
    
    int solve(int n)
    {
    	int len = 0;
    	int ans = 0;
    	while (n) {
    		d[++len] = n % b;
    		n /= b;
    	}
    
    	int cnt = 0; // 为1的位数
    	for (int i = len; i >= 1; --i) {
    		if (cnt == k) {
    			if (d[i]) {
    				++ans;
    				break;
    			}
    		} else if (i == 1) {
    			if (d[i] > 1 && cnt + 1 == k) ++ans;
    			break;
    		} else if (d[i] > 1) {
    			ans += dp[i - 1][k - cnt - 1] + dp[i - 1][k - cnt];
    			break;
    		} else if (d[i] == 1) {
    			ans += dp[i - 1][k - cnt];
    			++cnt;
    		}
    	}
    
    	return ans;
    }
    
    
    int main()
    {
    	init();
        while (cin >> x >> y >> k >> b) {
    		cout << solve(y + 1) - solve(x) << endl;
        }
        return 0;
    }
    
    /**
    Input:
    15 20 2 2
    1 300 4 8
    111 211 3 10
    90 100 2 3
    
    Output:
    3
    0
    1
    1
    **/
    

      

  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/wenruo/p/4730234.html
Copyright © 2011-2022 走看看