• ybt1192放苹果后续:正解


    ybt1192放苹果

    注:本篇为此篇后续

    真正的正解

    找规律

    上次的想法只是一时灵机一动,但小聪明是不能解决问题的,所以要理性地分析,在复杂的问题,经过分解都会变得简单。

    · · · · · ·
    盘子苹果 1 2 3 4 5
    1 1 1 1 1 1
    2 1 2 2 3 3
    3 1 2 3 4 5
    4 1 2 3 5 6
    5 1 2 3 5 7

    设i果j盘的方案数是f~i,j~

    在列表后可以发现,表格的第一行和第一列都是1,并且易知m或n为零时的方案数,这便是我们递推的边界条件。

    写出初始化代码:

    f[0][0]=1;
    for(int i=1;i<=10;i++) {
    	f[1][i]=1;
    	f[i][1]=1;
    	f[0][i]=1;
    	f[i][0]=0;
    }
    

    另外,在盘子比苹果多的时候,方案数不再随盘子的增多而增多。

    所以当i<j时,f~i,j~=f~i,i~

    要想进行递推,找清状态关系是关键,在列上文的表时,我是先将所有苹果放在第一个盘子里,然后一个一个往后拿,直到在保证苹果数量递减的前提下无法往后拿为止。一开始就会出现在后面的盘子里大量出现零的情况,那么我们就可以这样分类。

    [总方案=有空盘方案+无空盘方案 ]

    当有空盘时​,至少但不仅仅有一个盘子没放苹果,所以这时的问题就简化成j-1个盘子放i个苹果的情况;

    当没有空盘时,每个盘子有至少但不仅仅一个苹果,所以这时将每个盘子的第一个苹果去掉,问题就简化成将i-j个苹果放进j个盘子的情况。

    写出方程: f~i,j~=f~i,j-1~+f~i-j,j~

    /*完整代码*/
    #include<iostream>
    using namespace std;
    int f[15][15],t,m,n;
    int main() {
    	f[0][0]=1;
    	for(int i=1;i<=10;i++) {
    		f[1][i]=1;
    		f[i][1]=1;
    		f[0][i]=1;
    		f[i][0]=0;
    	}
    	for(int j=2; j<=10; j++) {//枚举盘子数
    		for(int i=2;i<=j;i++){//苹果比盘子少 
    			f[i][j]=f[i][i]; 
    		}
    		for(int i=j; i<=10; i++) {//枚举苹果数 
    			f[i][j]=f[i][j-1]+f[i-j][j];
    			//cout<<i<<"	"<<j<<"	"<<f[i][j]<<endl; //测试,重要,勿动!!!
    		}
    	}
    	cin>>t;
    	for(int k=1;k<=t;k++) {
    		cin>>m>>n;
    		cout<<f[m][n]<<endl;
    	}
    	return 0;
    }
    

    思路来自这里,感谢

  • 相关阅读:
    SSL certificate verify failed” using pip to install packages
    Getting The following errors when installing boto3
    D3 Scale functions
    Making a simple scatter plot with d3.js
    Basic scatterplot in d3.js
    D3 Tick Format
    CentOS定时备份mysql数据库和清理过期备份文件
    linux yum清除var目录下缓存的方法
    正则表达式纯数字校验
    每天一个Linux命令--查看当前登陆用户并强制退出
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/12213237.html
Copyright © 2020-2023  润新知