• Mr Youngs Picture Permutations 题解报告


    题目传送门

    【题目大意】

    给定行数以及每一行的的人数,求方案数,要求从前往后,从左往右身高递增。

    【思路分析】

    这里没有必要考虑究竟是怎么排的,只要方案数就好啦,然后看到数据范围最大是5行,那么就考虑DP

    设$f[a][b][c][d][e]$为第1行站了a个人,第2行站了b个人,第3行站了c个人,第4行站了d个人,第5行站了e个人的方案数

    接下来考虑一下转移方程。

    首先很明显的条件就是某一个位置在其左边和上面的位置都有人的情况下才可以安排人,这时这个位置的方案数就要加上安排之前的方案数

    然后还要注意一下开数组不能直接开$f[31][31][31][31][31]$,那样会爆空间。因为后面一行人数肯定不大于前面一行,所以我们可以只开$f[31][lceil31/2 ceil][lceil31/3 ceil][lceil31/4 ceil][lceil31/5 ceil]$

    【代码实现】

     1 #include<cstdio>
     2 #include<cstring>
     3 #define ll long long
     4 #define go(i,a,b) for(register int i=a;i<=b;i++)
     5 using namespace std;
     6 int k,n[6];
     7 ll f[31][31/2+1][31/3+1][31/4+1][31/5+1];
     8 int main(){
     9     while(1){
    10         scanf("%d",&k);
    11         if(k==0) return 0;
    12         memset(n,0,sizeof(n));memset(f,0,sizeof(f));
    13         go(i,1,k) scanf("%d",&n[i]);
    14         f[0][0][0][0][0]=1;
    15         go(a,0,n[1]) go(b,0,n[2]) go(c,0,n[3]) go(d,0,n[4]) go(e,0,n[5]){
    16             ll as=f[a][b][c][d][e];
    17             if(a<n[1]) f[a+1][b][c][d][e]+=as;
    18             if(b<n[2]&&b<a) f[a][b+1][c][d][e]+=as;
    19             if(c<n[3]&&c<b) f[a][b][c+1][d][e]+=as;
    20             if(d<n[4]&&d<c) f[a][b][c][d+1][e]+=as;
    21             if(e<n[5]&&e<d) f[a][b][c][d][e+1]+=as;
    22         }
    23         printf("%lld
    ",f[n[1]][n[2]][n[3]][n[4]][n[5]]);
    24     }
    25     return 0;
    26 }
    代码戳这里
  • 相关阅读:
    -bash: belts.awk: command not found
    PLS-00357: Table,View Or Sequence reference 'SEQ_TRADE_RECODE.NEXTVAL' not allowed in this context
    初识makefile
    proc:基本数据库操作
    ORA-12154: TNS:could not resolve the connect identifier specified
    简单的爬虫
    合并一个文文件夹下的所有Excel文件
    Python 递归读取文件夹内所有文件名(包含子文件夹)
    CSS
    JQ
  • 原文地址:https://www.cnblogs.com/THWZF/p/10884921.html
Copyright © 2020-2023  润新知