POJ 3252 递推关系
来源:互联网 发布:30岁的程序员何去何从 编辑:程序博客网 时间:2024/05/16 02:10
2015/2/19
递推。
给定一个区间内有多少个数,数的二进制中0的数量不比1少。
范围决定不能暴力(显而易见的)
利用递推求区间和的方式
区间【L, R】 -> 最后的形式是 Sum(R) - Sum(L - 1)
问题来了,如何求Sum(X)?
我选择的方式是,
输入N, M ,(以N为例) 把N转换成二进制 len为N 的二进制长度。
递推 (1 ~ len )位数的二进制数中满足条件的数有几个。
比如:2进制 2位数 中满足题目的数只有一个 10. 4位数 4个 1000 1001 1100 1010(然后去组合数学吧)这部分可以打表
然后麻烦的地方在于 10 -> 1010 ,如果你把i = 4 的情况算进去 ,那么有1100 符合算法 却不符合题意 1100-12 >10 ;
所以i = len 的情况还要独自考虑下。
遍历二进制数,从高位往低位,遇到1即可将其变成0,然后在计算下 1->0的时候之前位上的变化有几种。
反正很烦就对了(你打我呀)。
#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#include<climits>#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;typedef long long ll; #define mod 10007#define lson pos<<1,l,mid#define sc(n) scanf("%d",&n)#define rson pos<<1|1,mid+1,r#define pr(n) printf("%d\n",n)#define met(n,m) memset(n, m, sizeof(n))#define F(x,y,i) for(int i = x;i > y; i--)#define f(x,y,i) for(int i = x;i < y; i++)#define ff(x,y,i) for(int i = x;i <= y; i++)#define FF(x,y,i) for(int i = x;i >= y; i--) const int N=100500;const int inf = INT_MAX;int Max(int a,int b){return a>b?a:b;}int Min(int a,int b){return a<b?a:b;}int a1[1005],a2[1005];int ans[35];int turn(int x,int y){__int64 sum = 1;__int64 dum = 1;__int64 nnm = 1;f(0, y , i){nnm *=(x - i);dum *= i+1;}return (int)(nnm/dum) ;}int turn_0(int x){int num = x/2 - 1;__int64 sum = 1;__int64 dum = 1;__int64 nnm = 1;f(0, num , i){nnm *=(x -1 - i);dum *= i + 1;sum+=nnm/dum;}return (int)(sum);}int main() { int n, m, tot, x; ans[0] = ans[1] = 0; f(2,35,i) { ans[i] = turn_0(i); } f(2,35,i)ans[i] += ans[i-1]; while(~scanf("%d%d",&m,&n)) { int cnt1 = 0,cnt2 = 0; int sum1 = 0,sum2 = 0; int one1 = 0,one2 = 0; while(n) { a1[cnt1++] = n%2; if(a1[cnt1-1])one1++; n/=2; } m--;while(m){a2[cnt2++] = m%2;if(a2[cnt2-1])one2++;m/=2;} sum1 = ans[cnt1-1];sum2 = ans[cnt2-1];if(cnt1>1&&cnt1 >= one1*2)sum1++;if(cnt2>1&&cnt2 >= one2*2)sum2++; f(0,cnt1-1,i) { if(a1[i]) { one1--; if(cnt1 >= one1*2)sum1++; int num = cnt1/2 - one1; num = Min(num,i); f(1,num+1,j) { sum1 += turn(i,j); } } } f(0,cnt2-1,i) { if(a2[i]) { one2--; int num = cnt2/2 - one2; if(cnt2 >= one2*2)sum2++; num = Min(num,i); f(1,num+1,j) { sum2 += turn(i,j); } } } printf("%d\n",sum1 - sum2); } return 0; }
0 0
- POJ 3252 递推关系
- POJ 1019 Number Sequence <递推关系>
- UVA11361 递推关系
- 递推关系
- POJ1850 递推关系
- poj1019 递推关系
- poj 2704 递推
- poj 1737 递推
- POJ 2029 递推
- POJ 3176 递推
- 几个经典递推关系
- uva12034(递推关系)
- uva580(递推关系)
- uva11464(递推关系)
- POJ 3298 递推,DP
- poj 2229 Sumsets 递推
- poj 2663 递推问题
- POJ 2531 DFS + 递推
- Linux安装node.js
- hdu 1285 确定比赛名次 简单的拓扑排序模板题~~需要注意重边
- 辛星浅析kill、pkill的区别
- POJ 3565 Ants
- 例题10-1 巨大的斐波那契数! UVa11582
- POJ 3252 递推关系
- UVA - 11292 Dragon of Loowater
- codeforces 166e Tetrahedron 水dp
- UVA - 11729 Commando War
- uva 11300 - Spreading the Wealth(数论)
- hdu 1021 (找规律题)
- 【ACM打卡】ZOJ 1414 3100
- Android SDK更新太慢解决方法
- 程序性能优化