Acwing 271. 杨老师的照相排列
生活随笔
收集整理的這篇文章主要介紹了
Acwing 271. 杨老师的照相排列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Acwing 271. 楊老師的照相排列
題意:
有n個數分別是從1到n,現在排成k排,每排分別有Ci個數,要求每排每列的都是從小到大,問有多少種方案
題解:
因為每行每列都是單調的,因此我們可以從小到大一次考慮1 ~ n的位置。在任意時刻,已經安排好的位置的數在每一行都是遞增關系的(因為我們是從小到大的安排),每個數都插在隊尾。我們用一個5元組來表示每行的人數,(a1,a2,a3,a4,a5),ai表示第i行已經安排好的人數,當此時考慮下一步(即再安排一個新人時),我們考慮所有滿足如下條件的行號i:
從上往下考慮,如果當前行未滿,并且當前行人數小于上一行。(如果上一行人數比本行小,那應該優先放在上一行,記住我們是從小到大放置,所以必須順序放,不然無法保證單調性)
如果滿足條件,就對該行進行轉移,該行人數+1,加上上一個狀態的方案。
我們不需要關心(a1,a2,a3,a4,a5)這些已經排好的具體方案,其描述的輪廓內的合影方案總數就構成一個子問題。
注意直接開數組會爆,使用動態開數組
代碼:
#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b); typedef long long ll; using namespace std; //Fe~Jozky const ll INF_ll=1e18; const int INF_int=0x3f3f3f3f; inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } void rd_txt(){#ifdef ONLINE_JUDGE#elsefreopen("in.txt","r",stdin);#endif } int k; int a[10]; int main() {//rd_txt();while(cin>>k){if(k==0)break;a[1]=a[2]=a[3]=a[4]=a[5]=0;for(int i=1;i<=k;i++){cin>>a[i];}unsigned int f[a[1]+2][a[2]+2][a[3]+2][a[4]+2][a[5]+2];memset(f,0,sizeof(f));f[0][0][0][0][0]=1;for(int i1=0;i1<=a[1];i1++){for(int i2=0;i2<=a[2];i2++){for(int i3=0;i3<=a[3];i3++){for(int i4=0;i4<=a[4];i4++){for(int i5=0;i5<=a[5];i5++){unsigned int x=f[i1][i2][i3][i4][i5];if(i1<a[1])f[i1+1][i2][i3][i4][i5]+=x;if(i2<a[2]&&i2<i1)f[i1][i2+1][i3][i4][i5]+=x;if(i3<a[3]&&i3<i2)f[i1][i2][i3+1][i4][i5]+=x;if(i4<a[4]&&i4<i3)f[i1][i2][i3][i4+1][i5]+=x;if(i5<a[5]&&i5<i4) f[i1][i2][i3][i4][i5+1]+=x;}}}}}cout<<f[a[1]][a[2]][a[3]][a[4]][a[5]]<<endl;}return 0;}總結
以上是生活随笔為你收集整理的Acwing 271. 杨老师的照相排列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初七人日节祝福语 初七人日节的唯美祝福语
- 下一篇: Acwing 273. 分级