标签:blog io os sp for div on log amp
有两种DP搞法,不过其实本质上是一样的。。。
一种是按照题解上说的记录当前到i位,进位为j的种类数,转移的时候直接枚举在这一位上面放多少个1就好了。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #include <cmath> #include <climits> using namespace std; typedef long long LL; const LL mod = 1e9 + 9; int bits[64], k, n; LL f[64][10000 + 10]; void getbits(int num) { memset(bits, 0, sizeof(bits)); for(int i = 0; i <= 30; i++) bits[i] = (bool)(num & (1 << i)); } LL dfs(int now, int over, LL nownum) { if(now == 30) return over == 0; if(nownum > n) return 0; if(f[now][over] != -1) return f[now][over]; LL ret = 0; for(int i = 0; i <= k; i++) { if(nownum + (i << now) > n) break; if((over + i) % 2 == bits[now]) { ret += dfs(now + 1, (over + i - bits[now]) >> 1, nownum + (i << (now))); ret %= mod; } } if(f[now][over] == -1) f[now][over] = ret % mod; return ret % mod; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &k, &n); memset(f, -1, sizeof(f)); getbits(n); cout << dfs(0, 0, 0) << endl; } return 0; }
另外一种是记录当前位i构成和为j的种类数,转移的时候也是枚举在当前为放多少个1.
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #include <cmath> #include <climits> using namespace std; const int maxn = 1e4 + 10; typedef long long LL; const LL mod = 1e9 + 9; LL f[30][maxn]; int main() { int T; scanf("%d", &T); while(T--) { int n, k; scanf("%d%d", &k, &n); memset(f, 0, sizeof(f)); for(int i = 0; i <= k && i <= n; i++) f[0][i] = 1; for(int i = 0; i < 16; i++) { for(int j = 0; j <= n; j++) if(f[i][j]) { for(int t = 0; t <= k; t++) { LL nxt = ((LL)t << (i + 1)) + j; if(nxt > n) break; f[i + 1][nxt] = (f[i + 1][nxt] + f[i][j]) % mod; } } } cout << f[16][n] << endl; } return 0; }
标签:blog io os sp for div on log amp
原文地址:http://www.cnblogs.com/rolight/p/4096057.html