UVA - 11375 Matches

来源:互联网 发布:otc机器人编程 编辑:程序博客网 时间:2024/06/07 11:34

题意:求用n个火柴能组成几个非负整数,火柴不必用完,前导0是不能存在的

思路:把“已经用过火柴数i”表示状态,以后每添加一个数字x就转移状态i到i+c[x](c[x]表示x 用到的火柴数),因为没有前导0,所以状态为0的时候是不能添加数字0的(最后当n>=6的时候再添加一个代表0)

令d[i]表示到i状态的个数,利用加法原理,因为可以不必用完火柴,所以答案是:

d[1]+...d[n]

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 510;struct node{    int p[MAXN];    int len;    node(){        memset(p,0,sizeof(p));        len = 0;    }    node(int a){        p[0] = a;        len = 1;    }    node operator +(const node &a) const{        node b;        b.len = max(len,a.len);        for (int i = 0; i < b.len; i++){            b.p[i] += p[i] + a.p[i];            b.p[i+1] = b.p[i] / 10;            b.p[i] %= 10;        }        if (b.p[b.len] > 0)            b.len++;        return b;    }    void out(){        if (len == 0)            printf("0\n");        else {            for (int l = len-1; l >= 0; l--)                printf("%d",p[l]);            printf("\n");        }    }}d[2005];int c[] = {6,2,5,5,4,5,6,3,7,6};int main(){    d[0].p[0] = 1,d[0].len = 1;    for (int i = 0; i < 2001; i++)//前导0不行        for (int j = 0; j < 10; j++)            if (!(i==0 && j==0) && i+c[j] < 2001)                d[i+c[j]] = d[i+c[j]] + d[i];    d[6] = d[6] + node(1);    for (int i = 2; i < 2001; i++)        d[i] = d[i] + d[i-1];    int n;    while (scanf("%d",&n) != EOF && n > 0)        d[n].out();    return 0;}



0 0