SCU 4426 Counting_3 (dp)

题目链接

4426: Counting_3

Submit your solution     Discuss this problem     Best solutions

Time Limit: 1000ms

Description

Define f(0)=1 and f(n) to be the number of different ways n can be expressed as a sum of integer powers of 3 using each power no more than 3 times.
For example, f(9)=3 since there are 3 ways to express 9:
    1+1+1+3+3
    3+3+3
    9
For a given n, please calculate f(n).

Input

Line 1: T, indicating the number of test cases.
Line 2 - T+1: n (1 <= n <= 10^18)

Output

For each case, output f(n) in a line.

Sample Input

2
9
10

Sample Output

3
2

Author

huangshenno1 


题意:把一个数n,分成若干个 3的某次方的数的和,每个数不能超过3个。求有多少种分法?

题解:显然要先把n转换为三进制的数,这显然是一种满足条件的方案,每一位最大为2。接下来就容易想到dp了。

用dp[i][j] 表示最高位到第i+1位都合法,第i位为j 的方案数 。转移见代码:

#include<cstdio>
#include<cstring>
#include<set>
#include<iostream>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<queue>
#include<cctype>
#include<algorithm>
#define inff 0x3fffffff
#define nn 8100000
#define mod 1000000007
typedef long long LL;
using namespace std;
LL n;
int a[50];
LL dp[50][5];
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&n);
        int ix=0;
        while(n)
        {
            a[ix++]=n%3;
            n/=3;
        }
        memset(dp,0,sizeof(dp));
        dp[ix][0]=1;
        for(i=ix-1;i>=0;i--)
        {
            for(j=0;j<=3;j++)
            {
                dp[i][a[i]]+=dp[i+1][j];
                if(a[i]<2)
                    dp[i][a[i]+3]+=dp[i+1][j+1];
            }
        }
        printf("%lld\n",dp[0][0]+dp[0][1]+dp[0][2]+dp[0][3]);
    }
    return 0;
}




你可能感兴趣的:(dp,ACM)