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

来源:互联网 发布:阿金库尔战役 知乎 编辑:程序博客网 时间:2024/06/05 00:32

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 310using 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图像为:




原创粉丝点击