cf 431D 二分+数位DP
来源:互联网 发布:炮哥捏脸数据 编辑:程序博客网 时间:2024/06/06 14:24
题意:给定 M, K,求一个数N,使得 N+1,N+2, .....,N*2 这些数中有M个数的二进制表示含有K个1
思路:
N的范围为1e18次方,然后又没有好的公式来求
所以可以试一下二分+数位DP判断
yy了下,要是mid求得的 个数小于M,则mid应该变大,反之则要变小。。。。
写了下真的可以,1A
AC代码如下:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int digit[100], tot;__int64 dp[100][100][2];__int64 M, K;__int64 DFS( int pos, int presum, bool st ){ if( pos < 0 ){ if( presum == K ){ return 1; }else{ return 0; } } if( !st && dp[pos][presum][st] != -1 ){ return dp[pos][presum][st]; } __int64 ans = 0; int endd = st ? digit[pos] : 1; for( int i = 0; i <= endd; i++ ){ ans += DFS( pos - 1, presum + i, st && i == endd ); } return dp[pos][presum][st] = ans;}__int64 solve( __int64 n ){ tot = 0; while( n ){ digit[tot++] = n % 2; n /= 2; } memset( dp, -1, sizeof( dp ) ); return DFS( tot - 1, 0, true );}int main(){ __int64 l, r, mid; scanf( "%I64d%I64d", &M, &K ); l = 1; r = 1e18; while( l <= r ){ mid = ( l + r ) / 2; __int64 t = solve( mid * 2 ) - solve( mid ); if( t == M ){ printf( "%I64d\n", mid ); return 0; }else if( t < M ){ l = mid + 1; }else{ r = mid - 1; } } return 0;}
0 0
- cf 431D 二分+数位DP
- 数位dp cf 55d
- CF 55D 数位dp
- CF 55D 数位DP
- CF 55D(数位DP)
- 数位dp CF 55 D. Beautiful numbers
- 数位dp CF 55D Beautiful numbers
- CF D. Beautiful numbers (数位dp)
- [数位dp] cf 55D Beautiful numbers
- cf 55D 数位dp 好题
- CF-55D-数位DP-Beautiful Number
- CF 55D Beautiful numbers (数位DP)
- CF - 55D 数位dp + 状压
- CF 55D - Beautiful numbers(数位DP)
- cf-279D - The Minimum Number of Variables-数位dp
- CF #287 div2 D The Maths Lecture 数位DP
- cf 401D. Roman and Numbers 数位dp,状压
- 【CF ECR8-D】Magic Numbers(数位dp)
- 转载和积累系列 - CentOS 网络配置
- 【实用随记】浏览器端定位
- zigbee事件
- 关于intent中传输字符串丢失的解决…
- adb pull/push
- cf 431D 二分+数位DP
- 转:ubuntu修改计算机名和加入wind…
- 华为2014机考题:输入1--50个数字,求出最小数和最大数的和
- 转:Ubuntu上可使用的15个桌面环境
- 转:Windows 7硬盘安装Ubuntu…
- 分享:Python快速教程(转)
- 转:控制Android LED灯颜色代…
- 6 个重构方法可帮你提升 80% 的代码质量
- 转:MTK Android 修改默认日期时间