首页 > 其他分享 >[ABC237F] |LIS| = 3

[ABC237F] |LIS| = 3

时间:2023-03-05 18:56:08浏览次数:48  
标签:int ABC237F len 最小值 LIS dp define

[ABC237F] |LIS| = 3 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题的技巧性很强:
考虑到最长上升子序列的长度只有3.

我们令DP[长度][所有LIS=1最后一个元素的最小值][所有LIS=2最后一个元素的最小值][所有LIS=3最后一个元素的最小值]为方案数。

为什么这样令dp呢,因为这样令可以让 LIS=1转移到LIS=2,LIS=2转移到LIS=3

重点:若dp[len][i][j][k]存在,则显然有一条重要信息:i<j<k.

技巧:显然会存在LIS=1存在,但LIS=2不存在或LIS=1和LIS=2存在,但LIS=3不存在的情况

一般来说我们默认0即不存在的条件,但是这与 i<j<k不是很符合。所以我们令 m+1为LIS=1不存在的情况,m+2为LIS=2不存在的情况,m+3为LIS=3不存在的情况,这样能满足 (i<j<k) 。

最终初始化:dp[len][m+1][m+2][m+3]=1;

对于dp[len][][][],显然枚举dp[len]的第二,第三,第四维是不好的,因为这样枚举很难转移。

但是dp[len-1][i][j][k]是知道的,我们将dp[len-1][i][j][k]转移到dp[len][][][]。

这样便只差最后一个条件,第 len 位的值,所以我们再枚举第 len 的值 p.

因为有i<j<k,所以p有四种情况。

1.p<=i<j<k.则LIS=1的最后一个元素的最小值为p:dp[len][p][j][k]=(dp[len][p][j][k]+dp[len-1][i][j][k])%MOD;

2.i<p<=j<k,则LIS=2可以 由LIS=1的 i 加一个 p组成 LIS=2,此时所有LIS=2最后一个元素的最小值为p:dp[len][i][p][k]=(dp[len][i][p][k]+dp[len-1][i][j][k])%MOD;

3.i<j<p<=k则LIS=3可以 由LIS=2的 j 加一个 p 组成LIS=3,此时所有LIS=3最后一个元素的最小值为p:dp[len][i][j][p]=(dp[len][i][j][p]+dp[len-1][i][j][k])%MOD;

4.i<j<k<p,此时LIS=4,不符合题意。

最后统计所有的dp[n][i][j][k]即可。

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=1e3+10;
const int M=20;
const int MOD=998244353;
//const int inf=0x3f3f3f3f;     
//const ll INF=0x3ffffffffffff;
int T,n,m,dp[N][M][M][M];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read(),m=read(); 
    dp[0][m+1][m+2][m+3]=1;
    for(int len=1;len<=n;len++)
        for(int i=1;i<=m+1;i++)
            for(int j=i+1;j<=m+2;j++)
                for(int k=j+1;k<=m+3;k++)
                    for(int p=1;p<=m;p++)
                    {
                        if(p<=i) dp[len][p][j][k]=(dp[len][p][j][k]+dp[len-1][i][j][k])%MOD;
                        else if(p<=j) dp[len][i][p][k]=(dp[len][i][p][k]+dp[len-1][i][j][k])%MOD;
                        else if(p<=k)  dp[len][i][j][p]=(dp[len][i][j][p]+dp[len-1][i][j][k])%MOD;
                        // p>l 就是LIS=4的情况了 
                    }
    int ans=0;
    for(int i=1;i<=m;i++)
        for(int j=i+1;j<=m;j++)
            for(int k=j+1;k<=m;k++)
                ans=(ans+dp[n][i][j][k])%MOD;
    printf("%d",ans);
    return 0;
}

 

 

 

 

标签:int,ABC237F,len,最小值,LIS,dp,define
From: https://www.cnblogs.com/Willette/p/17181290.html

相关文章

  • JavaSE——ArrayList集合练习
    packagecom.zhao.test2;publicclassPhone{privateStringlogo;privateIntegerprice;publicPhone(){}publicPhone(Stringlogo,I......
  • APP学习5(ListView和Adapter)
    1.ListViewListView是以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示。   2.常用数据适配器(Adapter)BaseAdapter是基本的适配器,实际上是一个抽......
  • Android学习-ListView再视
    之前接触了一点ListView的基础知识,但没有自己去敲,学的不是很深刻,今天我按照教程,写了一个listview的基本实现,基本掌握了listviewlistview的学习是为了给RecyclerView打一下......
  • map list 和set
    List输出的顺序和输入的顺序一致,允许重复。Set输出的顺序和输入的顺序不一致,不允许有重复数据List和Set继承Collection接口,所以增加方法是一样的add(),获取元素时,Lis......
  • JavaSE——集合ArrayList
    集合和数组的优势对比:长度可变添加数据的时候不需要考虑索引,默认将数据添加到末尾1.1ArrayList类概述什么是集合提供一种存储空间可变的存储模型,存储的数据......
  • Android studio ListView的界面
    新建.java文件,定义一个实体类bt_list_adapter_type.java,作为ListView适配器的适配类型;publicclassbt_list_adapter_type{privateStringname;privateintim......
  • 常用的互相转化int[]、Integer[]和List<Integer>
    publicclassArr2List{publicstaticvoidmain(String[]args){int[]data={4,5,3,6,2,5,1};//int[]转List<Integer>Lis......
  • Java集合LinkedList源码中 实现 List 接口 却没有 在 LinkedList实现全部的 List接口
    Java集合LinkedList源码中实现List接口却没有在LinkedList实现全部的List接口方法普通类实现接口,应该实现接口中全部的抽象方法。难道是源码实现接口有什么特殊的......
  • tomcat启动乱码,淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.lo
    logging日志:淇℃伅[main]org.apache.catalina.startup.VersionLoggerListener.log鏈嶅姟鍣ㄧ増鏈解决方法:tomcat地址/conf/logging.properties,将UTF-8全部替换为GBK。......
  • STATA: inlist inrange应用
    //建立新变量vv,其值:trunk只能为11或17,mpg可以从18-30间时为1,其他为0genvv=inlist(trunk,11,17)&inrange(mpg,18,30)//建立新变量vva,其值:trunk为11-17,mpg可以从18-30......