首页 > 其他 > 详细

UVA - 11375 Matches

时间:2014-02-13 06:38:46      阅读:341      评论:0      收藏:0      [点我收藏+]

题意:求用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;
}



UVA - 11375 Matches

原文:http://blog.csdn.net/u011345136/article/details/19126309

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!