链接:HDU6578 - Blank

题意:

有 n (≤100) 个格子,向其中填入 0、1、2、3 这4个数,但是有 m (≤100) 个限制

限制 l r x :表示 l ~ r 的格子内不同的数的个数为x

问一共有多少种填入方案?


分析:

构建 dp[i][j][k][t][cur]i,j,k,t 分别表示0,1,2,3出现的最后位置,cur表示填到了第 cur 个格子

根据已求得的 dp[i][j][k][t][cur-1] 可以得到以下状态转移方程(下一位分别填0,1,2,3):
dp[cur][j][k][t][cur]=dp[cur][j][k][t][cur]+dp[i][j][k][t][cur−1]dp[i][cur][k][t][cur]=dp[i][cur][k][t][cur]+dp[i][j][k][t][cur−1]dp[i][j][cur][t][cur]=dp[i][j][cur][t][cur]+dp[i][j][k][t][cur−1]dp[i][j][k][cur][cur]=dp[i][j][k][cur][cur]+dp[i][j][k][t][cur−1]dp[cur][j][k][t][cur]=dp[cur][j][k][t][cur]+dp[i][j][k][t][cur-1]\\ dp[i][cur][k][t][cur]=dp[i][cur][k][t][cur]+dp[i][j][k][t][cur-1]\\ dp[i][j][cur][t][cur]=dp[i][j][cur][t][cur]+dp[i][j][k][t][cur-1]\\ dp[i][j][k][cur][cur]=dp[i][j][k][cur][cur]+dp[i][j][k][t][cur-1]dp[cur][j][k][t][cur]=dp[cur][j][k][t][cur]+dp[i][j][k][t][cur−1]dp[i][cur][k][t][cur]=dp[i][cur][k][t][cur]+dp[i][j][k][t][cur−1]dp[i][j][cur][t][cur]=dp[i][j][cur][t][cur]+dp[i][j][k][t][cur−1]dp[i][j][k][cur][cur]=dp[i][j][k][cur][cur]+dp[i][j][k][t][cur−1]

这样对于每一个限制,当 cur == r 时,根据 0,1,2,3出现的最后位置i,j,k,t 是否 >= l,可以得出有 几个不同的数若不等于x,则dp值变为0

空间复杂度 O(N5),时间复杂度 O(N5)

时间和空间复杂度都达到了5方,要进行优化。

优化①

可以发现因为 i,j,k,t 表示某个数最后一次出现的位置,那么一定有一个是等于 cur 的,而且互不相等(除非为0,即尚未填入)

那么就可以构建 dp[i][j][k][cur] ,其中 i < j < k < cur (若为0可等于)只知道 i, j, k, cur 是不同的数最后出现的位置,且i < j < k < cur (并不需要知道 i,j,k,cur对应的填入数是哪个,因为这并不影响对限制的判断)

根据已求得的 dp[i][j][k][cur-1],得到新的状态转移方程为:(注意这里是i<j<k<cur-1 )
dp[j][k][cur−1][cur]=dp[j][k][cur−1][cur]+dp[i][j][k][cur−1]dp[i][k][cur−1][cur]=dp[i][k][cur−1][cur]+dp[i][j][k][cur−1]dp[i][j][cur−1][cur]=dp[i][j][cur−1][cur]+dp[i][j][k][cur−1]dp[i][j][k][cur]=dp[i][j][k][cur]+dp[i][j][k][cur−1]dp[j][k][cur-1][cur]=dp[j][k][cur-1][cur]+dp[i][j][k][cur-1]\\ dp[i][k][cur-1][cur]=dp[i][k][cur-1][cur]+dp[i][j][k][cur-1]\\ dp[i][j][cur-1][cur]=dp[i][j][cur-1][cur]+dp[i][j][k][cur-1]\\ dp[i][j][k][cur]=dp[i][j][k][cur]+dp[i][j][k][cur-1]\\ dp[j][k][cur−1][cur]=dp[j][k][cur−1][cur]+dp[i][j][k][cur−1]dp[i][k][cur−1][cur]=dp[i][k][cur−1][cur]+dp[i][j][k][cur−1]dp[i][j][cur−1][cur]=dp[i][j][cur−1][cur]+dp[i][j][k][cur−1]dp[i][j][k][cur]=dp[i][j][k][cur]+dp[i][j][k][cur−1]
分别表示 将最后一次出现位置为 i, j, k ,cur-1的数填入第cur个格子中

这样时间复杂度和空间复杂度都优化到 O(N4),时间勉强可以,但是空间还是过大了。

优化②

可以发现 dp[][][][cur] 其实只和 dp[][][][cur-1] 有关,那么就可以用滚动数组再节省一下空间

构建 dp[i][j][k][2],得到状态转移方程:
dp[j][k][cur−1][now]=dp[j][k][cur−1][now]+dp[i][j][k][pre]dp[i][k][cur−1][now]=dp[i][k][cur−1][now]+dp[i][j][k][pre]dp[i][j][cur−1][now]=dp[i][j][cur−1][now]+dp[i][j][k][pre]dp[i][j][k][now]=dp[i][j][k][now]+dp[i][j][k][pre]dp[j][k][cur-1][now]=dp[j][k][cur-1][now]+dp[i][j][k][pre]\\ dp[i][k][cur-1][now]=dp[i][k][cur-1][now]+dp[i][j][k][pre]\\ dp[i][j][cur-1][now]=dp[i][j][cur-1][now]+dp[i][j][k][pre]\\ dp[i][j][k][now]=dp[i][j][k][now]+dp[i][j][k][pre]\\ dp[j][k][cur−1][now]=dp[j][k][cur−1][now]+dp[i][j][k][pre]dp[i][k][cur−1][now]=dp[i][k][cur−1][now]+dp[i][j][k][pre]dp[i][j][cur−1][now]=dp[i][j][cur−1][now]+dp[i][j][k][pre]dp[i][j][k][now]=dp[i][j][k][now]+dp[i][j][k][pre]

注意: 因为这里是累加,所以用滚动数组时,dp[i][j][k][pre]用完以后要清空!

最终空间复杂度为O (2*N3),时间复杂度 O(N4)


以下代码:

#include<bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
using namespace std;
const int INF=0x3f3f3f3f;
const LL MOD=998244353;
const int maxn=100+10;
int main()
{int T;scanf("%d",&T);while(T--){int n,m;vector<PII> lim[maxn];scanf("%d %d",&n,&m);for(int i=1;i<=m;i++){int l,r,x;scanf("%d %d %d",&l,&r,&x);lim[r].push_back(PII(l,x));   //以r分类存入限制}LL dp[maxn][maxn][maxn][2]={0};int now=1,pre=0;dp[0][0][0][pre]=1;for(int cur=1;cur<=n;cur++){for(int k=0;k<max(cur-1,1);k++)   //只有等于0时,i,j,k,cur才存在相等for(int j=0;j<max(k,1);j++)   //否则满足 i<j<k<curfor(int i=0;i<max(j,1);i++){dp[j][k][cur-1][now]=(dp[j][k][cur-1][now]+dp[i][j][k][pre])%MOD;dp[i][k][cur-1][now]=(dp[i][k][cur-1][now]+dp[i][j][k][pre])%MOD;dp[i][j][cur-1][now]=(dp[i][j][cur-1][now]+dp[i][j][k][pre])%MOD;dp[i][j][k][now]=(dp[i][j][k][now]+dp[i][j][k][pre])%MOD;dp[i][j][k][pre]=0;   //用完记得要清空}for(int k=0;k<max(cur,1);k++)for(int j=0;j<max(k,1);j++)for(int i=0;i<max(j,1);i++){for(int p=0;p<lim[cur].size();p++){PII t=lim[cur][p];               //cur是一定在[l,r]内的if((i>=t.first)+(j>=t.first)+(k>=t.first)+1!=t.second)dp[i][j][k][now]=0;}}swap(now,pre);}//求和当cur==n时的dp值,即为最终答案LL ans=0;for(int k=0;k<max(n,1);k++)for(int j=0;j<max(k,1);j++)for(int i=0;i<max(j,1);i++)ans=(ans+dp[i][j][k][pre])%MOD; //因为最后now和pre多换了一次,所以这里是preprintf("%lld\n",ans);}return 0;
}

2019多校第一场 HDU6578 - Blank(DP,思维,滚动数组优化空间)相关推荐

  1. 2019HDU多校第一场 HDU6578 Blank

    http://acm.hdu.edu.cn/showproblem.php?pid=6578 题意:一排有N个空格.空格从左到右依次为1.2.-.N. 汤姆正在用{0,1,2,3}中的一个数字填充每个 ...

  2. 2019HDU多校第一场1001 BLANK (DP)(HDU6578)

    2019HDU多校第一场1001 BLANK (DP) 题意:构造一个长度为n(n<=10)的序列,其中的值域为{0,1,2,3}存在m个限制条件,表示为 l r x意义为[L,R]区间里最多能 ...

  3. 信息学奥赛一本通1267:【例9.11】01背包问题(二维dp与滚动数组优化)

    [题目描述] 一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,. ...

  4. 【2019多校第一场补题 / HDU6578】2019多校第一场A题1001Blank——dp

    HDU6578链接 题意 有一串字符串,仅由 {0,1,2,3}\{0, 1, 2, 3\}{0,1,2,3} 组成,长度为 nnn,同时满足 mmm 个条件.每个条件由三个整数组成:l.r.xl.r ...

  5. 【hdu6588】2019多校第一场K题function,反演

    题目 枚举gcd,最后化简得∑i=1n3φ(x)∑i=1⌊nx⌋[x∣⌊xi3⌋]\sum^{\sqrt[3]{n}}_{i=1}φ(x)\sum^{\lfloor \frac n x\rfloor} ...

  6. 2020 HDU多校 第一场 04-Distinct Sub-palindromes(思维)

    题目链接: 04-Distinct Sub-palindromes Description 题意:给定n,求长度为n的字符串中包含的不同次回文串的数目的最大值 S is a string of len ...

  7. 2019年杭电多校第一场 1001题blank(DP)HDU6578

    2019年杭电多校第一场 1001题blank(DP)HDU6578 解决思路,开一个DP数组来存储0 1 2 3四个字符最后出现的位置,并且在DP中已经==排好序==. DP开四维,DP[i][j] ...

  8. HDU-6578 Blank(DP)2019暑假杭电多校第一场

    题意:一行有n个空格编号1~n; 每一个空格中填入0,1,2,3中的一个数字.且满足m个限制l,r,x:满足在区间[l,r]正好有x种不同的数字. 有多少种方法可以填充空格以满足所有条件? 思路:dp ...

  9. HDU 2019 Multi-University Training Contest 1 杭电2019多校联合训练赛 第一场 1001 Blank (6578)

    HDU 2019 Multi-University Training Contest 1 杭电2019暑期多校集训第一场 1001 Blank (6578) Problem Description T ...

最新文章

  1. [HEOI2016/TJOI2016]排序
  2. RESTful Web 服务 - Java (JAX-RS)
  3. 【SSL协议】SSL协议详解
  4. [WCF]NetTcpBinding在IIS中使用的详细配置方法
  5. 雷军公布小米高管团队:仅15位,常程位列其中
  6. java 唯一流水号_JAVA流水号生成规格,采用同步单例生成,保证永远唯一
  7. 文末有福利 | 6大理由,告诉你为什么这个大会你不能错过!
  8. 8.Kong入门与实战 基于Nginx和OpenResty的云原生微服务网关 --- 指标监控与报警
  9. vue.js引入外部CSS样式和外部JS文件的方法
  10. C语言练习题,鸡兔同笼
  11. php获取sqlserver时间,PHP_php操作sqlserver关于时间日期读取的小小见解,上周五,要做一个php 同时对mys - phpStudy...
  12. (stream流)List转Map
  13. XTTS V4.3 跨平台迁移12.1.2 HPUX ->Oracle Linux
  14. 三国杀全武将台词大全(标准+神话再临+一将成名12345+SP+国战+其他+皮肤)
  15. java生成订单唯一编号_java唯一订单号生成
  16. 用好这 28 个工具,开发效率爆涨|云效工程师指北
  17. [UER#9]知识网络
  18. 我怎么看技术人员去创业公司这件事
  19. BERT!BERT!BERT!
  20. JCTF 2014 -小试身手

热门文章

  1. 24.4. Prompting
  2. MuMu模拟器是干什么用的?MuMu模拟器Mac版对电脑配置要求是什么?
  3. MMdetection中backbone的实现-MobileNetV2
  4. 合作:对应fork来的项目进行修改操作
  5. Permissions 0777 for xxx are too open
  6. STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁
  7. 《论文写作》课堂收获
  8. 为任意屏幕尺寸构建 Android 界面
  9. Bootstrap里的圆角outline
  10. 游戏界的“扛把子”,“3D 游戏之父”, 约翰•卡马克的传奇人生