[USACO06NOV] Round Numbers S

题面

# include <iostream>
# include <cstdio>
# include <cstring>
# define MAXN 35

int a[MAXN];
int f[MAXN][MAXN][MAXN];
// f[i][j][k] 二进制下 最高位为第 i 位,有 j 个 1 和 k 个 0 的圆数个数

int DFS(int dep, int on, int off, bool eq, bool fz){
	if(!dep){
		return off >= on ? (!fz) : 0;
	}

	if((!eq) && (!fz) && (~f[dep][on][off])){
		return f[dep][on][off];
	}

	int lim = eq ? a[dep] : 1;

	int ans = 0;
	for(int i = 0; i <= lim; i++){
		// if(i){
		//	ans += DFS(dep-1, on+1, off, (eq && (i == a[dep])), 0);
		// }
		// else{
		//	ans += DFS(dep-1, on, off+1, (eq && (i == a[dep])), fz&&(!i));
		// }
                // 以上是错误示范

		if(fz && (!i)){
			ans += DFS(dep-1, 0, 0, (eq)&&(i == a[dep]), 1);
		}
		else{
			if(i){
				ans += DFS(dep-1, on+1, off, (eq && (i == a[dep])), 0);
			}
			else{
				ans += DFS(dep-1, on, off+1, (eq && (i == a[dep])), 0);
			}
		}
	}

	if((!fz) && (!eq)){
		f[dep][on][off] = ans;
	}

	return ans;
}

int DP(int now){
	memset(f, -1, sizeof(f));
	a[0] = 0;

	for(	; now; now>>=1){
		a[++a[0]] = now&1;
	}

	return DFS(a[0], 0, 0, 1, 1);
}

int main(){
	int l, r;
	std::cin>>l>>r;
	std::cout<<DP(r) - DP(l-1);
	return 0;
}
posted @ 2020-09-05 22:06  ChPu437  阅读(80)  评论(0编辑  收藏  举报