• nyoj1076-方案数量 【排列组合 dp】


    http://acm.nyist.net/JudgeOnline/problem.php?pid=1076

    方案数量

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:2
     
    描述

    给出一个N*M的棋盘,左下角坐标是(0,0),右上角坐标是(N,M),规定每次只能向上或者向右走,问从左下角走到右上角,一共有多少种方案。上图是一个4*3的棋盘。

     
    输入
    多组测试数据。
    每组输入两个整数N,M(0≤N,M≤30)。
    输入0,0时表示结束,不做任何处理。
    输出
    对于每组测试数据,输出对应的方案数。
    样例输入
    4 3
    2 2
    0 0
    样例输出
    35
    6




    解题思路A:ans = C(n+m, n)。因为从左下角走到右上角一共要走n+m步,往上要走n步,如果用1表示向上走,用0表示向右走,则相当于给n+m个数进行赋值,其中n个数被赋值为1,求有多少种赋值方法。只需从n+m个数里挑出n个,有C(n+m, n)中挑选办法。
    代码:
     1  
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 #define ll long long
    10 
    11 ll Permutation(ll a,ll x);
    12 
    13 int main(){
    14     ll m,n;
    15     while(scanf("%lld %lld",&m,&n),m||n){
    16         printf("%lld
    ",Permutation(m+n,n));
    17     }
    18     return 0;
    19 }
    20 ll Permutation(ll a,ll x){
    21     ll ans=1;
    22     for(ll i=1;i<=x;i++)   ans=ans*(a-i+1)/i;
    23     return ans;
    24 }
    25         
    View Code

    这里想提一点就是,虽然只有部分地方必须longlong,但是类型转换要耗不少时间,故而采取所有地方都使用longlong。

    解题思路B:因为如果要到(n, m)点,要么从(n-1, m)点过来,要么从(n, m-1)点过来,设dp[i][j]表示从(0, 0)到(i, j)有多少种方案,

    则dp[i][j] = dp[i-1][j] + dp[i][j-1],最后输出dp[n][m]就是答案。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 #define ll long long
     9 #define N 35
    10 
    11 ll dp[N][N];
    12 
    13 void GetAns();
    14 
    15 int main(){
    16     GetAns();
    17     int m,n;
    18     while(scanf("%d %d",&m,&n),m||n){
    19         printf("%lld
    ",dp[m][n]);
    20     }
    21     return 0;
    22 }
    23 void GetAns(){
    24     int m=30,n=30;
    25     dp[0][0]=1;
    26     for(int z=1;z<=60;z++){
    27         for(int i=0;i<=n;i++){
    28             int j=z-i;
    29             if(j>m) continue;
    30             dp[i][j]=0;
    31             if(i)   dp[i][j]+=dp[i-1][j];
    32             if(j)   dp[i][j]+=dp[i][j-1];
    33         }
    34     }
    35 }
    View Code
  • 相关阅读:
    jQuery(四)
    jQuery(三)
    jQuery(二)
    jQuery(一)
    JS(四)
    JS(三)
    JS(二)
    类似openDialog的弹窗
    vue的异步组件按需加载
    vue实现点击、滑动右侧字母对应各个城市
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4305703.html
Copyright © 2020-2023  润新知