UVA11375【火柴拼数Matches】-------2015年1月27日

一:题意描述

本题主要是讲给定n个火柴,用这n个火柴去拼数,问最后可以拼成多少种?

二:问题分析

我们需要找出状态:假设当我们把已经使用的火柴数i当做一个状态。当i=0时,我们从这个状态可以转化成状态2(数字1),3(数字7),4(数字4),5(数字2,3,5),6(数字6,9(数字0此时不行)),7(数字8)。当i不等于0时,我们可以从这个状态转化成状态(i+2)(数字1),(i+3)(数字7),(i+4)(数字4),(i+5)(数字2,3,5),(i+6)(数字0,6,9(这里可以包括0)),(i+7)(数字8)。

分析到这里,我们首先用公式定义状态:

dp[i]:使用了i个火柴可以拼凑的数字数目

dp[i+c[j]]+=dp[i];

那么最后的种数等于dp[1]+dp[2]+·····+dp[n]。当n>=6时我们还需要增加1表示数字0.

三:AC代码

#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 2000+10
int c[10]={6,2,5,5,4,5,6,3,7,6};
long long  dp[maxn];
void  process()
{
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    for(int i=0;i<maxn;i++)
        for(int j=0;j<10;j++)
    {
        if(!(i==0&&j==0)&&(i+c[j]<maxn))
        dp[i+c[j]]+=dp[i];
    }
}

int main()
{
    process();
    int n;
    while(cin>>n)
    {
        long long sum=0;
        for(int i=1;i<=n;i++)
             sum+=dp[i];
       if(n>=6)  cout<<sum+1<<endl;
         else  cout<<sum<<endl;
    }
    return 0;
}