uva 10313 整数拆分——硬币凑价

pay the price

http://www.cnblogs.com/staginner/archive/2011/11/30/2269491.html

给你一个价格n,求在指定使用的硬币个数范围内付款的方案数,后面可能给你边界a,b,也可能不给,不给的话个数是1-n,给一个a就是1-a,给两个是a-b

直接开二维数组背包的话会算重复,比如凑6的话,1、2、3,,2、1、3,3、1、2,一种方案就数了三遍,需加一维限制大小,dp[i][j][k]中用j个硬币凑成价格i,j个硬币中最大的硬币面值最大是k,dp[i][j][k]+=dp[i-k][j-1][t], 1<=t<=k.但这样规模会太大

这个题目涉及到一个结论,用不超过j个硬币凑出面值i的方案种数,是和用面值不超过j的硬币凑出面值i的方案种数是相同的。说得再数学一点,就是整数i拆分成不超过j个整数的拆分数,是和整数i拆成若干个值不超过j的整数的拆分数是相同的。具体的证明用到了Ferrers图像的性质。

    这样的话我们就可以取一个二维数组f[i][j]表示用面值不超过j的硬币凑出面值i的方案的种数,那么如果我使用了面值j,对应方案种数就应该加上f[i-j][j],如果我们不使用面值j,那么对应的方案种数就应该加上f[i][j-1]。也就是说状态转移方程为f[i][j]= f[i-j][j]+ f[i][j-1]。

#include<stdio.h>
#include<string.h>
#include<iostream>
#define N 310
using namespace std;
long long f[N][N];
int n,a,b;
char s[200];
int main()
{
    int i,j,k,l;
    memset(f,0,sizeof(f));
    /*
    for(i=0;i<=300;i++)
        f[0][i]=1;
    for(i=0;i<=k;i++)
    {
        for(j=1;j<=i;j++)
        {
            if(i>=j)
                f[i][j]+=f[i-j][j]; //用j
            f[i][j]+=f[i][j-1];//没用j
        }
    }
    这样不对,j比i大的时候,f[i][j]还是0,即每次用了j时f[i][j]加上的情况f[i-j][j]一直是0,少算了,f[i][j],当i比j小的时候依然有用
    */
	f[0][0]=1;
	k=300;
    for(i=0;i<=k;i++)
    {
        for(j=1;j<=k;j++)
        {
            if(i>=j)
                f[i][j]+=f[i-j][j]; //用j
            f[i][j]+=f[i][j-1];//没用j
        }
    }
    while(gets(s)!=NULL)
    {
        a=b=-1;
        sscanf(s,"%d%d%d",&n,&a,&b);
        //sscanf中没有读取成功将不会改变原值
        if(a==-1&&b==-1)
            a=1,b=n;
        else if(a!=-1&&b==-1)
            b=a,a=1;
        printf("%lld\n",f[n][b]-f[n][a-1]);
    }
    return 0;
}
百度百科

Ferrers图像

图像概念

一个从上而下的n层格子,mi 为第i层的格子数,当mi>=mi+1(i=1,2,,n-1) ,即上层的格子数不少于下层的格子数时,称之为Ferrers图像。 [1]

图像性质

(1)每一层至少有一个格子;
  (2)第一行与第一列互换,第二行与第二列互换,…,所得到的图象仍然是Ferrers图象,这两个 Ferrers图象称为是一对共轭的Ferrers图象。
性质(2)

  性质(2)

图像应用

(a) 整数n拆分成k个数的和的拆分数,和数n拆分成最大数为k的拆分数相等。因整数n拆分成k个数的和的拆分可用一k行的图像表示。所得的Ferrers图像的共轭图像最上面一行有k个格子。例如:
24=6+6+5+4+3
5个数,最大数为6
再如:
24=5+5+5+4+3+2
6个数,最大数为5
(b) 整数n拆分成最多不超过m个数的和的拆分数,和n拆分成最大不超过m的拆分数相等。 理由与(a)类似。
(c) 整数n拆分成互不相同的若干奇数的和的拆分数,和n拆分成自共轭的Ferrers图像的拆分数相等。
设n=(2n1+1)+(2n2+1)+……+2(nk+1),其中n1>n2>……nk。
构造一个Ferrers图像,其第一行,第一列都是n1+1格,对应于2n1+1,第二行,第二列各n2+1格,对应于2n2+1。依此类推。由此得到的Ferrrers图像是共轭的。反过来也一样。
例如:17=9+5+3
对应的Ferrers图像为:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值