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 9For 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;
}