POJ3252 Round Numbers 组合数学

这题目做了两个小时,调试的头都晕了。。。

题型是数位DP中很常见的,给一个区间[l,r]求区间[l,r]中的 符合题目要求的数的个数,本题求的 是 区间中 的数 它的二进制中0的个数大于等于1的个数的 这些数的个数,不好意思表达能力有点差。。。例如[1,4]答案是2, 因为 2的二进制是10,0的个数大于等于1的个数,4的二进制是100,0的个数大于1的个数,所以答案是两个

好了第一反应肯定是 设定一个函数 f(r) – f[l – 1]就是答案,那么显然这个函数f(r)的意思就是 1 到 r之间符合要求的数的个数,很容易想到数位DP,但是真心不好推啊,由于推数位DP的过程中对每个数的二进制 都画了一下,后来发现了 组合数学其实也是可以做的,

首先每一个数化为二进制数 第一位肯定是1,那么剩下的位数中 让一定的位数 上的数字为0就可以达到目的,例如 1 {}{}{} 其中{}表示空位,剩下的三个空位中至少让两个为0即可,那么答案其实就是 C(3,2) + C(3,3),跟组合数联系上了,那么就好办了

首先 把一个数m处理成二进制数,假设长度为n,那么 所有 长度为[1,n-1]的数 中 合法的 个数很容易就求出来了,直接扫一遍 然后判断它的长度再求组合数即可

接下来的部分就是分析 长度等于n的 且 大小必须小于等于m的 数中 合法的个数,有点麻烦,就是扫他的二进制数,若扫到的当前位上的数字为1,那么就令这个位置上的数为0,这样当前二进制表示的数 肯定是小于m的,这样就对于还未扫到的位 上的数 进行组合数求解答案即可,具体见代码中的注释部分

郁闷的是,我做的时候脑子有点糊涂,做到一半曲解了题目的意思,求的是 [l,r]中 数的二进制中1的个数大于0的个数的 这些数的个数,还好答案直接由总数减一下就可以了。。。不然就惨了。。。

int s,e;int bin[33];const int MAXN = 33;int C[33+1][33+1];int cnt = 0;void Initial() {int i,j;for(i=0; i<=33; ++i) {C[0][i] = 0;C[i][0] = 1;}for(i=1; i<=33; ++i) {for(j=1; j<=33; ++j)C[i][j] = (C[i-1][j] + C[i-1][j-1]);}}void init() {}bool input() {while(cin>>s>>e) {return false;}return true;}void Binary(int n) {memset(bin,0,sizeof(bin));cnt = 0;while(n) {bin[cnt++] = n&1;n >>= 1;}}int slove(int n) {if(n == 0)return 0;int ret = 0;Binary(n);for(int i=cnt – 1;i>0;i–) {//统计所有二进制数长度小于n的,可以自由组合数int tmp = (i – 1);if(tmp&1)tmp = (tmp>>1) + 1;else tmp >>= 1;for(int j=tmp;j<=i – 1;j++) {ret += C[i – 1][j];//cout<<C[i – 1][j]<<endl;}}int mark1 = 1,mark2 = 0;for(int i=cnt – 1;i>0;i–) {//统计长度与n相同的且小于等于n的if(bin[i – 1]) {int tmp;if(cnt&1)tmp = (cnt + 1)>>1;else tmp = (cnt>>1) + 1;//长度为cnt的至少需要多少个1tmp = tmp – mark1;//减去前面已经扫到的1的个数,当前至少还需几个1if(tmp < 0)tmp = 0;//有可能前面已经超过了需要的1的个数,这里需要注意,置0,WA出翔for(int j= tmp;j<=i – 1;j++)ret += C[i – 1][j];mark1++;//这个必须放最后,因为当前为0,不是必须为1,调试了半年}else mark2++;}ret += mark1>mark2?1:0;//写到最后发现我无意曲解了题意,,ret = n – ret;//我求的是一个数的二进制中1大于0的个数,那么好办求反就可以了return ret;}void cal() {cout<<slove(e) – slove(s – 1)<<endl;}void output() {}int main() {Initial();while(true) {init();if(input())return 0;cal();output();}return 0;}

总有看腻的时候,不论何等荣华的身份,

POJ3252 Round Numbers 组合数学

相关文章:

你感兴趣的文章:

标签云: