There are four combinations of coins to pay ten credits:
ten 1-credit coins,
one 4-credit coin and six 1-credit coins,
two 4-credit coins and two 1-credit coins, and
one 9-credit coin and one 1-credit coin.
Your mission is to count the number of ways to pay a given amount using coins of Silverland.
OutputFor each of the given amount, one line containing a single integer representing the number of combinations of coins should be output. No other characters should appear in the output.
Sample Input
2 10 30 0Sample Output
1 4 27
题意:给你1个n,你有 1 4 9 16 25 ..... i^2 等元素,每个有无限个,现在问你你有几种方案,由任意个元素组成n
比如
10 4种方案
1+9
1+1+....+1(10个)
4+1+.....+1(6个)
4+4+1+1
解:c1[i]=j代表的是组成i的方案有j种,c2的意义和c1相同,不过c2是再引入1个新的元素后,方案的变化,然后我们把c2的值赋给c1,c2重新归零
比如 10
我们首先明白可以组成他的元素为 1,4,9,因为每个元素有无限个,不过我们得知道c1[0]=1,因为1个都不选也是一种状态
我们先拿出 元素k= 1 ,显然 for( i ,0 , 10) c1[i] =1 唯一的方案就是 i 个1
然后拿出 元素 k=4 从 for(i,0,10),每个i 都可以 一直加k 直到值大于 10为止
0 : c2[0]+=c1[0] c2[4]+=c1[0] c2[8]+=c1[0]
1: c2[1]+=c1[1] c2[5]+=c1[1] c2[9]+=c1[1]
2 : c2[2]+=c1[2] c2[6]+=c1[2] c2[10]+=c1[2]
............
然后我们把c2的值赋给c1,清空c2
拿出 元素 k=9 for(i,0,10) 每个i 都可以 一直加k 直到值大于 10为止
0:c2[0]+=c1[0] c2[9]+=c1[0]
............
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
int c1[330],c2[330];
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<=n;i++)//元素 1 的情况
{
c1[i]=1;
c2[i]=0;
}
for(int i=2;i*i<=n;i++) //枚举小于等于n的元素
{
for(int j=0;j<=n;j++)//范围,因为最大只要到n即可
{
for(int k=0;k<=n;k+=i*i)//看最多能加几个当前元素
{
c2[j+k]+=c1[j];
}
}
for(int j=0;j<=n;j++)//更新c1,c2
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1[n]);
}
}