hihocoder #1076 与链 dp
Posted reverymoon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder #1076 与链 dp相关的知识,希望对你有一定的参考价值。
直接背包不可做
我们只需要知道每个数位上有多少个$1$,那么我们就能构造出解
因此,我们对每一位讨论,
可以拆出$n + frac{n}{2} + frac{n}{4} + ... = 2n$个物品,然后去做背包
加上足够的剪枝就可以过了...
复杂度$O(Tn^2)$
#include <set> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> namespace remoon { #define re register #define de double #define le long double #define ri register int #define ll long long #define sh short #define pii pair<int, int> #define mp make_pair #define pb push_back #define fi first #define se second #define tpr template <typename ra> #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++) #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --) #define gc getchar inline int read() { int p = 0, w = 1; char c = gc(); while(c > ‘9‘ || c < ‘0‘) { if(c == ‘-‘) w = -1; c = gc(); } while(c >= ‘0‘ && c <= ‘9‘) p = p * 10 + c - ‘0‘, c = gc(); return p * w; } int wr[50], rw; #define pc(iw) putchar(iw) tpr inline void write(ra o, char c = ‘ ‘) { if(!o) pc(‘0‘); if(o < 0) o = -o, pc(‘-‘); while(o) wr[++ rw] = o % 10, o /= 10; while(rw) pc(wr[rw --] + ‘0‘); pc(c); } tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; } tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; } tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; } } using namespace std; using namespace remoon; #define sid 200050 #define mod 1000000009 inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; } inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; } int n, k; int f[sid], g[sid][2]; inline void Solve() { int flag; memset(g, 0, sizeof(g)); k = read(); n = read(); int now = 0, pre = 1; g[now][0] = 1; rep(i, 0, 20) { now ^= 1; pre ^= 1; flag = 0; memset(f, 0, sizeof(f)); rep(j, 0, k) { if((1 << i) * j > n) break; f[(1 << i) * j] = 1; flag = 1; } if(flag == 0) { flag = i - 1; break; } rep(j, 0, n) g[j][now] = 0; rep(j, 0, n) if(f[j]) rep(p, 0, n) { if(j + p > n) break; inc(g[j + p][now], g[p][pre]); } } write(g[n][now]); } int main() { int Tt = read(); while(Tt --) Solve(); return 0; }
以上是关于hihocoder #1076 与链 dp的主要内容,如果未能解决你的问题,请参考以下文章