【DP_构成状态的种类数】HDU 1398 Square Coins

HDU 1398 Square Coins

  • 题意:有1->17的平方数价值的金币,问用这些金币组成1->300内任意价值,有多少种组合方法。
  • 思路:我们从小到大依次用这些平方数来组成1->300的价值
    1:dp[ i ]=1;
    4:dp[ 4 ]+=dp[ 4-4 ]=2; dp[ 5 ]+=dp[ 5-4 ]=2; dp[ 9 ]+=dp[ 9-4 ]=3;
    9:dp[ 9 ]+=dp[ 9-9 ]=4;
  • 所有的数都能被1组成,这毫无疑问
  • 举dp[ 8 ]=dp[ 8-4 ]+1=dp[ 4 ]+1(这里的1是完全由1组成8的情况)为例,8我们来想的话,有2x4,1x4,8x1,三种情况(不够的用1来补)。
  1. 8x1是跑1,每个dp[ i ]都变成了1(也就是0个4的情况)。
  2. 之后跑4,4=1x4=4x1(包含了0个4和1个4的情况),dp[ 8 ]+=dp[ 8-4 ]=dp[ 4 ],也就是包含了1个4,和2个4的情况。(也就是:8-4是一个4了,然后dp[ 4 ]有0个4和1个4的情况,于是dp[ 8 ]就包含了1个4,2个4的情况)
  • 再来说说14,有14x1,1x4,2x4,3x4,1x9,4+9(不够的用1来补)六种情况。
  1. 跑到1,就是全是1的情况。
  2. 跑到4,dp[ 14 ]+=dp[ 14-4 ],dp[ 10 ]包含了2个4,1个4,0个4(没有包含1个9的情况是因为还没跑9),所以可以构成dp[ 14 ]现在有3个4,2个4,1个4。
  3. 跑到9的时候,dp[ 14 ]+=dp[ 14-9 ],这里的dp[ 5 ]是有了0个4,1个4两种情况,这两种和9来组合,就是1个9,4和9组合这两种

【自己手动模拟一遍其实很简单】

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define P(x) x>0?x:0
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
typedef vector<int>:: iterator VITer;
const int maxn=305;
int coin[18];
void ConstInt()
{
    for(int i=0;i<=17;i++)
        coin[i]=i*i;
}
int N;
int dp[maxn];
void init()
{
    memset(dp,0, sizeof(dp));
    dp[0]=1;
}
void solve()
{
    init();
    for(int i=1;i<=17;i++)
        for(int j=coin[i];j<=300;j++)
            dp[j]+=dp[j-coin[i]];
}
int main()
{
    ConstInt();
    solve();
    while(~scanf("%d",&N) && N)
        printf("%d\n",dp[N]);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值