zoukankan      html  css  js  c++  java
  • timus1507 Amount of Degrees 按位DP

    http://acm.timus.ru/problem.aspx?space=1&num=1057

    其实这题可以算是一个组合数的题目了,主要是将基于其他进制转化为基于2进制的算法,对于某一位不为1的话,那么取其他位的话是一定不满足题意的,所以要找到一个数的最高位大于1,将这一位以及后面的每一位都赋值为1,然后就是一个按位DP的过程了,dp[len][statu]表示长度剩余量为len,要求1的个数为statu个时,并且对后面的位没有要求的情况下,所有可能的解。

    代码如下:

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    
    typedef unsigned int Int;
    
    Int x, y, k, b, bit[35];
    
    int len, dp[35][35];
    
    Int dfs(int pos, int statu, int limit)
    { 
        if (pos == -1) {
            return statu == 0;
        }
        if (!limit && dp[pos][statu] != -1) return dp[pos][statu];
        Int sum = 0;
        int s, end = limit ? bit[pos] : 1;
        for (int i = 0; i <= end; ++i) {
            s = statu;
            if (i == 1) s = statu - 1;
            if (s < 0) continue;
            sum += dfs(pos-1, s, limit && i==end);
        }
        if (!limit) {
            dp[pos][statu] = sum; // 如果有限制的话,那么end的取值是并没有取全的
        }
        return sum;
    }
    
    Int Cal(Int x)
    {
        len = -1;
        while (x != 0) { 
            bit[++len] = x % b;
            x /= b;
        }
        if (b != 2) {
        // 对于不是2进制的数,我们需要将其转化为2进制进行求解
        // 若一个数被表示为 a1*b^e1 + a2*b^e2 + a3*b^e3 次方,那么这个数要能成为题目中要求的数
        // 就要在把这个数缩小的情况下不对解带来影响,所以我们选择从高位开始的第一个系数既
        // 不是0又不是1的位来进行处理,并把从这一位开始的后面的所有的位都变成1,这样就是舍弃了
        // 一部分一定不会成为解的数,但是有会所有解空间
            for (int i = len; i >= 0; --i) {
                if (bit[i] > 1) {
                    for (int j = i; j >= 0; --j) {
                        bit[j] = 1;
                    }
                    break;
                }
            }
        }
        return dfs(len, k, 1);
    }
    
    int main()
    {    memset(dp, 0xff, sizeof (dp));
        while (scanf("%u %u %u %u", &x, &y, &k, &b) == 4) {
            x -= 1; 
            printf("%u\n", Cal(y) - Cal(x));
        }
        return 0;    
    } 
  • 相关阅读:
    树莓派的入网方式和远程连接
    数据结构与算法之递归(C++)
    c++中字符串输入注意的问题
    基于视觉的机械臂分拣(二)
    基于视觉的机械臂分拣(一)
    数据结构与算法之折半查找(C++)
    数据结构与算法之顺序查找(C++)
    ROS之USB摄像头识别二维码问题解决
    机械臂开发之正运动学
    利用vs pcl库将多个PCD文件合并成一张PCD地图
  • 原文地址:https://www.cnblogs.com/Lyush/p/2636552.html
Copyright © 2011-2022 走看看