http://acm.hdu.edu.cn/showproblem.php?pid=6578

不会做,看题解。

设dp[i][j][k][l]表示4种颜色出现的最后的位置分别是i,j,k,l的方法数,保证i>=j>=k>=l。其实不取=号,因为同一个位置不能放两个元素,除了开始的若干个比如dp[1][0][0][0]=4。

合法的转移叠加:

比如

刷新的颜色是i:dp[i+1][j][k][l]+=dp[i][j][k][l]

刷新的颜色是j:dp[i+1][i][k][l]+=dp[i][j][k][l]

刷新的颜色是k:dp[i+1][i][j][l]+=dp[i][j][k][l]

刷新的颜色是l:dp[i+1][i][j][k]+=dp[i][j][k][l]

假如从dp[i][j][k][l]转移到上述状态会导致新状态不满足约束则不进行这次转移,就太麻烦了。

由于是dp,其实只要遇到约束区间的右端点R的时候再考虑约束就可以了。

考虑四个数其实是[l,k,j,i],i肯定就是R,要是l>=L则有恰好4种颜色,否则要是k>=L则恰好3种颜色,否则要是j>=L则恰好2种颜色,否则只有1种颜色。

对每次转移后新状态的i维度必定是i+1,对i维度进行滚动节省空间。复杂度是精确的O(n4+mn3),据说很多队觉得过不了。

还卡memset???15组数据还卡memset?

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; inline int read() {
int x = 0;
char c = 0;
while(c < '0' || c > '9')
c = getchar();
while(c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x;
} inline void _write(int x) {
if(x > 9)
_write(x / 10);
putchar(x % 10 + '0');
} inline void write(int x) {
_write(x);
putchar('\n');
} struct Condition {
int l, r, x;
bool operator<(const Condition &c)const {
return r < c.r;
}
} con[105]; const int mod = 998244353;
int n, m, dp[2][105][105][105], ctop; inline void clear0(int n) {
for(int j = 0; j <= n; ++j) {
for(int k = 0; k <= j; ++k) {
for(int l = 0; l <= k; ++l) {
dp[n & 1][j][k][l] = 0;
}
}
}
} inline void clear1(int i, int L) {
//清除==1种的
for(int j = L - 1 ; j >= 0; --j) {
for(int k = j ; k >= 0; --k) {
for(int l = k ; l >= 0; --l) {
dp[i & 1][j][k][l] = 0;
}
}
}
} inline void clear2(int i, int L) {
//清除==2种的
for(int j = i ; j >= L; --j) {
for(int k = L - 1; k >= 0; --k) {
for(int l = k ; l >= 0; --l) {
dp[i & 1][j][k][l] = 0;
}
}
}
} inline void clear3(int i, int L) {
//清除==3种的
for(int j = i ; j >= L ; --j) {
for(int k = j ; k >= L; --k) {
for(int l = L - 1; l >= 0; --l) {
dp[i & 1][j][k][l] = 0;
}
}
}
} inline void clear4(int i, int L) {
//清除==4种的
for(int j = i ; j >= L ; --j) {
for(int k = j ; k >= L ; --k) {
for(int l = k ; l >= L; --l) {
dp[i & 1][j][k][l] = 0;
}
}
}
} inline void update1(int i) {
if(ctop > m || i < con[ctop].r)
return;
while(ctop <= m && i == con[ctop].r) {
//printf("cons %d\n", ctop);
int L = con[ctop].l, x = con[ctop].x;
++ctop;
if(x == 1) {
clear2(i, L);
clear3(i, L);
clear4(i, L);
} else if(x == 2) {
clear1(i, L);
clear3(i, L);
clear4(i, L);
} else if(x == 3) {
clear1(i, L);
clear2(i, L);
clear4(i, L);
} else {
clear1(i, L);
clear2(i, L);
clear3(i, L);
}
}
} inline void update2(int i, int j, int k, int l) {
dp[(i + 1) & 1][j][k][l] += dp[i & 1][j][k][l];
if(dp[(i + 1) & 1][j][k][l] >= mod)
dp[(i + 1) & 1][j][k][l] -= mod;
dp[(i + 1) & 1][i][k][l] += dp[i & 1][j][k][l];
if(dp[(i + 1) & 1][i][k][l] >= mod)
dp[(i + 1) & 1][i][k][l] -= mod;
dp[(i + 1) & 1][i][j][l] += dp[i & 1][j][k][l];
if(dp[(i + 1) & 1][i][j][l] >= mod)
dp[(i + 1) & 1][i][j][l] -= mod;
dp[(i + 1) & 1][i][j][k] += dp[i & 1][j][k][l];
if(dp[(i + 1) & 1][i][j][k] >= mod)
dp[(i + 1) & 1][i][j][k] -= mod;
} int solve() {
ctop = 1;
memset(dp[1], 0, sizeof(dp[1]));
dp[1][0][0][0] = 4;
update1(1);
for(int i = 1; i <= n - 1; ++i) {
//printf("i=%d\n", i);
clear0(i + 1);
for(int j = i; j >= 0; --j) {
for(int k = j ; k >= 0; --k) {
if(k == j && k)
continue;
for(int l = k ; l >= 0; --l) {
if(l == k && l)
continue;
update2(i, j, k, l);
}
}
}
update1(i + 1);
for(int j = i; j >= 0; --j) {
for(int k = j; k >= 0; --k) {
if(k == j && k)
continue;
for(int l = k ; l >= 0; --l) {
if(l == k && l)
continue;
//printf("dp[%d][%d][%d][%d]=%d\n", i + 1, j, k, l, dp[(i + 1) & 1][j][k][l]);
}
}
}
//printf("\n");
}
int ans = 0;
for(int j = n - 1; j >= 0; --j) {
for(int k = j ; k >= 0; --k) {
for(int l = k ; l >= 0; --l) {
ans += dp[n & 1][j][k][l];
if(ans >= mod)
ans -= mod;
}
}
}
return ans;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int T = read();
while(T--) {
n = read(), m = read();
for(int i = 1; i <= m; ++i) {
con[i].l = read(), con[i].r = read(), con[i].x = read();
}
sort(con + 1, con + 1 + m);
write(solve());
}
return 0;
}

2019 Multi-University Training Contest 1 - 1001 - Blank - dp的更多相关文章

  1. HDU 6362.oval-and-rectangle-数学期望、微积分 (2018 Multi-University Training Contest 6 1001)

    2018 Multi-University Training Contest 6 6362.oval-and-rectangle 题意就是椭圆里画内接矩形,问你矩形周长的期望. 比赛的时候推了公式,但 ...

  2. HDU 6319.Problem A. Ascending Rating-经典滑窗问题求最大值以及COUNT-单调队列 (2018 Multi-University Training Contest 3 1001)

    2018 Multi-University Training Contest 3 6319.Problem A. Ascending Rating 题意就是给你长度为k的数列,如果数列长度k<n ...

  3. HDU 6298.Maximum Multiple-数学思维题(脑子是个好东西,可惜我没有) (2018 Multi-University Training Contest 1 1001)

    暑假杭电多校第一场,这一场是贪心场,很多贪心的题目,但是自己太菜,姿势挫死了,把自己都写吐了... 2018 Multi-University Training Contest 1 HDU6298.M ...

  4. 2019 Multi-University Training Contest 1 A.Blank(dp)

    题意:现在要你构造一个只有{0,1,2,3} 长度为n且有m个限制条件的序列 问你方案数 思路:dp[i][j][k][now]分别表示四个数最后出现的位置 最后可以滚动数组 优化一下空间 ps:我的 ...

  5. 2015 Multi-University Training Contest 1 - 1001 OO’s Sequence

    OO’s Sequence Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5288 Mean: 给定一个数列,让你求所有区间上满足 ...

  6. 2015 Multi-University Training Contest 3 1001 Magician

    Magician Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5316 Mean: n个数,2种操作,1是单点更新,2是询问区间 ...

  7. 2015 Multi-University Training Contest 4 1001 Olympiad

    代码: #include<cstdio> #include<cstring> #include<set> using namespace std; int vis[ ...

  8. 2019 Nowcoder Multi-University Training Contest 4 E Explorer

    线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...

  9. 2019 Nowcoder Multi-University Training Contest 1 H-XOR

    由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那 ...

随机推荐

  1. pymongo操作mongo数据库的查操作

    一:  数据结构 { "_id" : ObjectId("5de8a5b748a75a8d48b72bdc"), ", ", ", ...

  2. MySQL--全文索引作用、原理及使用注意

    作用 MySQL索引可以分为:主键索引.普通索引.唯一索引.全文索引.其中,全文索引应该是是比较特殊的,它只有少数的几个存储引擎支持,且只有类型为char.vchar.text的列能建立全文索引.以前 ...

  3. 《SaltStack技术入门与实践》—— Renderer组件

    Renderer组件 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 前面我们已经提过使用Python语言编写state.sls文件.在SaltSta ...

  4. 原创——Nginx基础

    Nginx基础 一.Nginx概述: Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx ...

  5. linux运维、架构之路-HAProxy反向代理

    一.HAProxy介绍          专业反向代理,支持双机热备支持虚拟主机,配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端节点出现故障, HAProxy会自动将该服务器摘除,故障恢复 ...

  6. 开始玩矩阵了!先来一道入门题![SDOI2008]递归数列

    [SDOI2008]递归数列 题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + c ...

  7. P1092 虫食算——题解

    题目传送 (据说官方正解为高斯消元,但用搜索也能过,这里就讲讲搜索算法吧.) 对于一道搜索题,首先考虑一下大体怎样搜索.因为要考虑加法的进位,所以从左往右搜索对于考虑进位来说十分麻烦,而从右往左搜索就 ...

  8. Twice Equation

    题目链接:https://nanti.jisuanke.com/t/A1541 题意:给你一个L,要你求一个不小于L的最小数字n,对于一个整数m,满足2*(m+1)*m=n*(n+1). 思路:打表找 ...

  9. three arrays

    three arrays 字典树上贪心 #include<bits/stdc++.h> using namespace std; ][][]; ][]; ]; ]; ][]; ][]; i ...

  10. sqlserver控制台-添加用户

    1.右键新建登陆名 2. 常规选项 3.服务器角色 4.用户映射