Boxes of Chocolates Again UVA

来源:互联网 发布:js除法取整不四舍五入 编辑:程序博客网 时间:2024/06/16 19:56

Boxes of Chocolates Again UVA - 10590

题目:https://odzkskevi.qnssl.com/7ee6f54041617f8f28cf81ea4c0484ec?v=1508356293

数的划分。
描述状态:f[i][j]:数i划分数不超过j的种树
状态转移方程:
f[i][j] = f[i][j-1]+f[i-j][j]
数i划分数不超过j的种树
=不划分出j时数i划分数不超过j-1的种树+划分出一个j后数i-j划分数不超过j的种树
存储:5000*5000*高精度数组,空间不够。考虑状态转移方程j只与j,j-1有关,所以可以状态压缩。此时将外层循环设为j内层设为i
初值:f[0][j] = 1;
高精度:考虑压位加速

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 5001;typedef long long LL;struct NUM{    LL a[200], tot;    NUM() {        memset(a, 0, sizeof a);        tot = 1;    }    NUM operator + (const NUM& b) const{        NUM c = b;        for (int i = 1; i <= tot; ++i)          c.a[i] += a[i];        c.tot = max(tot, c.tot);        for (int i = 1; i <= c.tot; ++i) {          c.a[i+1] += c.a[i] / (LL)1e14;          c.a[i] %= (LL)1e14;        }        if (c.a[c.tot+1]) c.tot++;        return c;    }    void print(){        printf("%lld", a[tot]);        for (int i = tot-1; i >= 1; --i)          printf("%014lld", a[i]);        printf("\n");    }}f[MAXN][2], ans[MAXN];int main(){    int n;    ans[0].a[1] = 1;    for (int j = 1; j <= 5000; ++j)      for (int i = 1; i <= 5000; ++i) {        if (i-j < 0) continue;        if (i-j >= j)          f[i][j%2] = f[i][(j-1)%2] + f[i-j][j%2];        else          f[i][j%2] = f[i][(j-1)%2] + ans[i-j];        if (i == j)  ans[i] = f[i][i%2];      }    while (scanf("%d", &n) != EOF) {      ans[n].print();    }    return 0;}
原创粉丝点击