组合数学里的题。。在我飞的引导下走上了数位dp的不归路。。。这样算不算开挂。。。。好羞涩
数位dp真的真的真的好好用!!!
数位dp真的真的真的好好用!!!
数位dp真的真的真的好好用!!!
重要的事说三遍 一入数位dp深似海 再也粗不来了。。。 用数位很好想……都不知道该怎么写题解。。。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
int dp[31][2][63];
int digit[31];
/*
big 0 1 平衡 防止负从31开始
hs 前导0
*/
int dfs(int pos,int big,bool hs,bool high)
{
if(pos == -1) return big >= 31;
if(!high && ~dp[pos][hs][big]) return dp[pos][hs][big];
int i,en,ans = 0,nbig;
bool nhs;
en = high? digit[pos]: 1;
for(i = 0; i <= en; ++i)
{
nbig = big, nhs = hs;
if(i)
{
nbig--;
nhs = 0;
}
else if(!hs) nbig++;
ans += dfs(pos-1,nbig,nhs,high && i == en);
}
if(!high) dp[pos][hs][big] = ans;
return ans;
}
int Solve(ll x)
{
int len = 0;
while(x)
{
digit[len++] = x%2;
x >>= 1;
}
return dfs(len-1,31,1,1);
}
int main()
{
memset(dp,-1,sizeof(dp));
ll st,en;/////////////////这里必须吐槽下…………今天不宜敲代码 上午数组开小了 hdoj的题 不断WA 这次还好 ll开成int 最关键输入还用的%lld。。。然后给了RE 找了半天突然发现了TOT
scanf("%lld %lld",&st,&en);
printf("%d\n",Solve(en) - Solve(st-1));
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/challengerrumble/article/details/47779311