题解 | #放苹果#

放苹果

http://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf

####这道题要注意边界条件,苹果和盘子那里的转移方程不太好理解,我尝试着解释一下,详情看代码

#include <algorithm>
#include <vector>

using namespace std;

int main() {
    int m,n;
    while(cin>>m>>n){
        vector<vector<int>> v(m+1,vector<int>(n+1,0));//这里有0个苹果和0个盘子
        //的边界条件以及m个苹果n个盘子的情况,数组应该是m+1,n+1
        for(int i =0;i<m+1;i++){
            v[i][0]=0;//这里思考比如1个苹果放0个盘子,这种情况是没有的设为0
            if(i>=1)
            v[i][1]=1;//放一个盘子只有一种放法
        }
        for(int i =0;i<n+1;i++){
            v[0][i]=1;//这里要注意了,0个苹果放i个盘子应该设为1,为什么?下面再解
            //解释
            if(i>=1)
            v[1][i]=1;//1个苹果放i个盘子应该只有1种放法
        }
        int temp;
        for(int i =1;i<m+1;i++){
            for(int j =1;j<n+1;j++){
                if(i>=j)temp=v[i-j][j];//这里要非常详细的理解一下,苹果数量比盘
                //子大的情况,举个例子4个苹果3个盘子的放法实际上分为几个互斥的
                //的事件1、4个苹果3个盘子独有的放法(就是要用到3个盘子)2、4个
                //苹果2个盘子独有的放法,3、4个苹果1个盘子独有的放法。0个盘子
                //没有放法,这里用i-j其实就是要求j个盘子独有的放法,比如4个
                //苹果把3个盘子都用上的放法和(4-3)=1个苹果放3个盘子是一样的。
                //好了这里可以知道为什么前面0个苹果i个盘子要设为1了,因为
                //这里的苹果数和盘子数相等的情况(i==j)i个苹果对j个盘子的放法
                //只有一种,其实就是0个苹果j个盘子的放法。
                else temp=0;//i<j的时候,i个苹果放到j-1个盘子和i放到j个盘子一样
                v[i][j]=v[i][j-1]+temp;//这里总的放法要把互斥的加起来。
                
                
            }
        }
        
        cout<<v[m][n]<<endl;
    }
}

全部评论

相关推荐

7 收藏 评论
分享
牛客网
牛客企业服务