• Mr. Young's Picture Permutations


    POJ

    题意:(N(N<=30))个人排队,规定要站成(K(K<=5))排,且每排站(a_i)个人((a_1+a_2+...+a_k=N)),队伍要保证从后到前,从左到右身高都单调递减(保证每个人的身高都不一样).求有多少种方案?

    分析:假设每次都有5排,不足排视作站0人.从高到低,用(1)~(N)给每个人编号,我们从第1号(最高的人)开始放起,我们只要知道当前的队伍站成了什么样子,就能知道要如何放下一个人.

    (f(b_1,b_2,b_3,b_4,b_5))表示第一排已经站了(b_1)个人......第5排已经站了(b_5)个人的方案数.

    (i=1)(b_i<a_i)时,(f(b_1+1,b_2,b_3,b_4,b_5)+=f(b_1,b_2,b_3,b_4,b_5))

    (i=2)(b_i<a_i)(b_{i-1}>b_i)时,(f(b_1,b_2+1,b_3,b_4,b_5)+=f(b_1,b_2,b_3,b_4,b_5))

    (i=3,4,5)同第2排一样.

    初始状态(f(0,0,0,0,0)=1),目标状态(f(a_1,a_2,a_3,a_4,a_5))

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    using namespace std;
    inline int read(){
        int s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    LL a[10],f[31][31][31][31][31];
    int main(){
        while(1){
    		int k=read();if(!k)break;
    		memset(a,0,sizeof(a));
    		for(int i=1;i<=k;i++)a[i]=read();
    		for(int b1=0;b1<=a[1];b1++)
    	    	for(int b2=0;b2<=a[2];b2++)
    				for(int b3=0;b3<=a[3];b3++)
    		 			for(int b4=0;b4<=a[4];b4++)
    						for(int b5=0;b5<=a[5];b5++)
    			    			f[b1][b2][b3][b4][b5]=0;
    		f[0][0][0][0][0]=1;
    		for(int b1=0;b1<=a[1];b1++){
    	    	for(int b2=0;b2<=a[2];b2++){
    				for(int b3=0;b3<=a[3];b3++){
    		    		for(int b4=0;b4<=a[4];b4++){
    						for(int b5=0;b5<=a[5];b5++){
    			    			for(int i=1;i<=k;i++){
    							if(i==1&&b1<a[1])
                                	f[b1+1][b2][b3][b4][b5]+=f[b1][b2][b3][b4][b5];
    							if(i==2&&b2<a[2]&&b1>b2)
                                	f[b1][b2+1][b3][b4][b5]+=f[b1][b2][b3][b4][b5];
    							if(i==3&&b3<a[3]&&b2>b3)
                                	f[b1][b2][b3+1][b4][b5]+=f[b1][b2][b3][b4][b5];
    							if(i==4&&b4<a[4]&&b3>b4)
                                	f[b1][b2][b3][b4+1][b5]+=f[b1][b2][b3][b4][b5];
    							if(i==5&&b5<a[5]&&b4>b5)
                                	f[b1][b2][b3][b4][b5+1]+=f[b1][b2][b3][b4][b5];
    			    			}
    						}
    		    		}
    				}
    	    	}
    		}
    		printf("%lld
    ",f[a[1]][a[2]][a[3]][a[4]][a[5]]);
        }
        return 0;
    }
    
    
  • 相关阅读:
    第二次作业
    初学JAVA的 感想 尹鑫磊
    初学JAVA 感想
    《将博客搬至CSDN》
    JAVA中的几种内部类
    JAVA-静态变量与实体变量
    teacher页面的代码
    测试说明书的概述和摘要
    网站的概述
    html与xhtml的区别
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10884739.html
Copyright © 2020-2023  润新知