1. 程式人生 > 實用技巧 >[USACO06NOV] Round Numbers S

[USACO06NOV] Round Numbers S

題目

\(\texttt{[USACO06NOV] Round Numbers S}\)

分析

數位 \(dp\) 入門題
一般我們需要當前位置 \(pos\),有無前導零 \(lead\),高位標記 \(limit\)
然後就依題弄

\(Code\)

#include<cstdio>
#include<cstring>
using namespace std;

int l , r , f[40][40][40] , a[40] , len;

int dfs(int pos , int s0 , int s1 , int lead , int limit)
{
	if (!pos) return s0 >= s1;
	if (f[pos][s0][s1] != -1 && !lead && !limit) return f[pos][s0][s1];
	int res = 0;
	for(register int i = 0; i <= (limit ? a[pos] : 1); i++)
	{
		if (!i && lead) res += dfs(pos - 1 , s0 , s1 , 1 , limit && (i == a[pos]));
		else res += dfs(pos - 1 , s0 + (i == 0) , s1 + (i == 1) , 0 , limit && (i == a[pos]));
	}
	if (!lead && !limit) f[pos][s0][s1] = res;
	return res;
}

int solve(int x)
{
	len = 0;
	while (x) a[++len] = x & 1 , x >>= 1;
	memset(f , 255 , sizeof f);
	return dfs(len , 0 , 0 , 1 , 1);
}

int main()
{
	scanf("%d%d" , &l , &r);
	printf("%d\n" , solve(r) - solve(l - 1));
}