271. 杨老师的照相排列 ###K ###K //K

题目链接:https://www.acwing.com/problem/content/273/

思路: 考虑按照1 2 3 递增来放数字, 每次如果要放一个数字,要保证左边一个位置一定要有

数字并且上面一个位置一定要有数字,否则后面的数字不管怎么放 都会不满足题意

dp[i][j][k][x][y] 为第1~5行放多少个数字的合法方案  划分子集的依据为 最后一个数放在了第几排,

注意 一定要满足 j<=i  k<=j 这样的条件 不然可能又非法状态转移过来

所以 u+=dp[i-1][j][k][x][y] …… dp[i][j][k][x][y-1]

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,int>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 
12 ll dp[31][31][31][31][31];
13 int a[6];
14 
15 
16 int main()
17 {
18     ios::sync_with_stdio(false);
19     cin.tie(0);
20     int n;
21     while(cin>>n,n)
22     {
23         memset(a,0,sizeof(a));
24         for(int i=1;i<=n;i++) cin>>a[i];
25         dp[0][0][0][0][0]=1;
26         for(int i=1;i<=a[1];i++)
27         {
28             for(int j=0;j<=i;j++)
29             {
30                 for(int k=0;k<=j;k++)
31                 {
32                     for(int x=0;x<=k;x++)
33                     {
34                         for(int y=0;y<=x;y++)
35                         {
36                             ll &u=dp[i][j][k][x][y];
37                             u=0;
38                             if(i) u+=dp[i-1][j][k][x][y];
39                             if(j) u+=dp[i][j-1][k][x][y];
40                             if(k) u+=dp[i][j][k-1][x][y];
41                             if(x) u+=dp[i][j][k][x-1][y];
42                             if(y) u+=dp[i][j][k][x][y-1];
43                         }
44                     }
45                 }
46             }
47         }
48         cout<<dp[a[1]][a[2]][a[3]][a[4]][a[5]]<<'\n';
49     }
50 
51 
52 
53 
54 
55 
56 
57 
58 }
View Code

 

posted @ 2021-04-03 15:34  canwinfor  阅读(66)  评论(0编辑  收藏  举报