码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder #1076 与链 dp

时间:2018-10-16 20:51:32      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:因此   getch   mem   sizeof   oid   name   utc   line   class   

技术分享图片

 

 

直接背包不可做

我们只需要知道每个数位上有多少个$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 = \n) {
        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

标签:因此   getch   mem   sizeof   oid   name   utc   line   class   

原文地址:https://www.cnblogs.com/reverymoon/p/9800442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!