• openjudge666:放苹果—题解


    (测试这里的markdown,同时也有纪念意义吧——第一次写的题解)
    当时刚学递推的时候做的一道题
    oj上的666题

    666:放苹果
    总时间限制: 1000ms 内存限制: 65536kB
    描述
    把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
    输入
    第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
    输出
    对输入的每组数据M和N,用一行输出相应的K。
    样例输入
    1
    7 3
    样例输出
    8

    当时学习不精的我看到直到题的时候心中一万匹飞过啊!
    好的咱们来认真的说一下这道题
    这道题用递推写的话肯定和前几项有关系
    什么关系呢?
    首先让我们先考虑所有盒子必须装东西的情况

    1.所有盒子的其中一个或多个里面只有一个苹果,则苹果数-1,盒子数-1,即dp[i-1][j-1]
    2.所有盒子均有超过一个的苹果

    然而,因为这道题里面说不可以有重复的方案,所以对于第二个选择,就可以这样想——
    将所有的盒子中全部拿出一个来(吃了),盒子数不变
    这样做保证了不会有重复的,即dp[i-j][j](因为最开始的dp[i][j]没有重复方案的话,那么dp[i-j][j]也只是将所有的数字全部-1,不改变原来的每个方案的不重复性,那么dp[i][j]方案数量扣除其中盒子含有一个苹果的情况数量,即等于dp[i-j][j],从而让状态不断地递归2,最终到达1,从而保证了方案的合法性)

    那么我们讨论了盒子至少放一个的情况,那么就有人问了,为什么说这个,题中不是允许空盒子吗?
    所以啊,我们只需要将原先苹果的数量加上盒子数,就能保障上述的成立,即每一个盒子里面至少都有一个苹果,那么我们再每个方案的每一个盒子中拿去一个苹果,不就有可能出现空盒子的方案吗?

    但是为什么这样写呢,因为第一种的解题思路与大多数的不重复放苹果问题是一类的(例题有很多,比如说数的划分),从上面的思路也很容易推出允许空盒子的方案数了

    上代码

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int dp[1000][1000]={0};//dp[m][n]
    int main()
    {
    	int t,m,n;
    	scanf("%d",&t);
    	for(int i=1;i<=t;i++){
    		memset(dp,0,sizeof(dp));
    		scanf("%d%d",&m,&n);
    		m+=n;
    		for(int j=0;j<=m;j++){
    			dp[j][j]=1;
    			if(j>0)dp[j][1]=1;
    		}
    		for(int j=1;j<=m;j++){
    			for(int k=1;k<=n&&k<=j;k++){
    				dp[j][k]=dp[j-1][k-1]+dp[j-k][k];
    			}
    		}
    		printf("%d
    ",dp[m][n]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    禁用生成8.3字符长文件名解决单目录存储大量文件写入性能下降问题
    遭遇EventSystem服务问题
    软件工程师遭遇硬件故障RAID5两块硬盘离线
    Pocket Player睡眠定时器不能选择问题的解决办法
    借助RamDisk让你的FireFox飞起来
    NVS4200M显卡“超频”
    Python数据类型
    Python变量
    端口及对应服务
    Python基础(1)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7532980.html
Copyright © 2020-2023  润新知