AcWing 271. 杨老师的照相排列

在这里插入图片描述
输入样例

1
30
5
1 1 1 1 1
3
3 2 1
4
5 3 3 1
5
6 5 4 3 2
2
15 15
0

输出样例

1
1
16
4158
141892608
9694845

这道题相对来说,我第一次感受到了压力吧,这道题我也看出来要是dfs一定百分百超时,要用dp做,用dp又不知道思路,无敌的yxc老师来了!!!!

https://www.acwing.com/video/397/

在这里插入图片描述
yxc老师yyds
讲的真很细
首先分几种情况:把每一排的最后一个数(最大的数插进去的点)类似于去除,然后加上这一形状的方案数,(就是这一形状的方案数),然后向前递归(直接从小到大就实现了),我自己脑子演示了一遍,这方法很好,但是我也有注意到要是上下两行相等的话不能去除,看到老师的代码,我就知道用if就可以解决问题。也学到了一个新的指针,干货很多呀

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=31;
LL f[N][N][N][N][N];
int s[6];
int main(void)
{
    int n;
    while(cin>>n,n)
    {
        memset(s,0,sizeof(s));
        for(int i=1;i<=n;i++)  cin>>s[i];
        memset(f,0,sizeof(f));
        f[0][0][0][0][0]=1;//因为求的是方案,要以此往后递推
        for(int a=0;a<=s[1];a++)
        for(int b=0;b<=s[2];b++)
        for(int c=0;c<=s[3];c++)
        for(int d=0;d<=s[4];d++)
        for(int e=0;e<=s[5];e++)
        {
            LL &v=f[a][b][c][d][e];//用指针操作减少了写代码的麻烦
           //每一行都要判断是否为0,并且是否减去这个还满足这个结构
            if(a&&a-1>=b) v+=f[a-1][b][c][d][e];
            if(b&&b-1>=c) v+=f[a][b-1][c][d][e];
            if(c&&c-1>=d) v+=f[a][b][c-1][d][e];
            if(d&&d-1>=e) v+=f[a][b][c][d-1][e];
            if(e) v+=f[a][b][c][d][e-1];
        } 
        cout<<f[s[1]][s[2]][s[3]][s[4]][s[5]]<<endl;
    }
}

在这里插入图片描述
然后数据多而且大,时间看起来像超时的样子。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值