HDU-6578 Blank(DP)2019暑假杭电多校第一场
题意:一行有n个空格编号1~n;
每一个空格中填入0,1,2,3中的一个数字。且满足m个限制l,r,x:满足在区间[l,r]正好有x种不同的数字。
有多少种方法可以填充空格以满足所有条件?
思路:dp[i][j][k][t]代表填完t个空格之后。4个数字出现的位置排序后为(i,j,k,t)的方法。
可以得到4个转移方程:
dp[j][k][t][t+1] += dp[i][j][k][cnt];
dp[i][k][t][t+1] += dp[i][j][k][cnt];
dp[i][j][t][t+1] += dp[i][j][k][cnt] ;
dp[i][j][k][t+1] += dp[i][j][k][cnt];
分别代表第t+1个位置的数字取 4个不同的数字。同时在转移之前需要将不满足限制状态清零(枚举以t为右边界的限制。如果在[l,r]的数字种类不等于x则清零)。
最后一维开滚动数组节省空间。
#include<bits/stdc++.h>
using namespace std;const int mod = 998244353;
typedef pair<int, int> piir;
const int maxn = 1e2 + 5;
int dp[maxn][maxn][maxn][2];
vector <piir> lims[maxn];int main() {
// freopen("in.txt", "r", stdin);int T; scanf("%d", &T);while(T--) {int n, m; scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++) lims[i].clear();int l, r, x;int ans = 0;while(m--) {scanf("%d%d%d", &l, &r, &x);lims[r].push_back(piir(l, x));}memset(dp, 0, sizeof(dp));dp[0][0][0][0] = 1;//边界for(int t = 0; t <= n; t++) {int cnt = t & 1;for(int k = 0; k <= t; k++)//初始化for(int j = 0; j <= k; j++)for(int i = 0; i <= j; i++)dp[i][j][k][cnt ^ 1] = 0;for(int k = 0; k <= t; k++)//将不满足限制的状态清零for(int j = 0; j <= k; j++)for(int i = 0; i <= j; i++)for(piir tem : lims[t])if(1 + (i >= tem.first) + (j >= tem.first) + (k >= tem.first) != tem.second) dp[i][j][k][cnt] = 0;//枚举以t为右边界的限制。如果在[l,r]的数字种类不等于x清零。for(int k = 0; k <= t; k++)//状态转移for(int j = 0; j <= k; j++)for(int i = 0; i <= j; i++) {dp[j][k][t][cnt ^ 1] = (dp[i][j][k][cnt] + dp[j][k][t][cnt ^ 1]) % mod;//t+1位置取4个不同数字时的情况。dp[i][k][t][cnt ^ 1] = (dp[i][j][k][cnt] + dp[i][k][t][cnt ^ 1]) % mod;dp[i][j][t][cnt ^ 1] = (dp[i][j][k][cnt] + dp[i][j][t][cnt ^ 1]) % mod;dp[i][j][k][cnt ^ 1] = (dp[i][j][k][cnt] + dp[i][j][k][cnt ^ 1]) % mod;}}for(int k = 0; k <= n; k++)//累加答案for(int j = 0; j <= k; j++)for(int i = 0; i <= j; i++)ans = (ans + dp[i][j][k][n & 1]) % mod;printf("%d\n", ans);
}return 0;
}
HDU-6578 Blank(DP)2019暑假杭电多校第一场相关推荐
- 2019年杭电多校第一场 1001题blank(DP)HDU6578
2019年杭电多校第一场 1001题blank(DP)HDU6578 解决思路,开一个DP数组来存储0 1 2 3四个字符最后出现的位置,并且在DP中已经==排好序==. DP开四维,DP[i][j] ...
- 2022“杭电杯”中国大学生算法设计超级联赛 (1) 杭电多校第一场 2 3 4 5 8 12
题目 1002 Dragon slayer 标程 1003 Backpack AC代码 1004 Ball AC代码 1008 Path AC代码 1009 Laser AC代码 1012 Alice ...
- 2019杭电多校第一场 Operation HDU - 6579
题意:给出一个序列,两种操作,求区间[l,r]的区间最大异或和,和在末尾添加一个数 思路:强制在线,保存每个线性基的数值,接下去直接去搜第r个线性基,但要保持时间比l要大,新增了一个pos数组代表一个 ...
- 2019杭电多校第一场 HDU 6599
题解 枚举所有的回文串 注意,本质不同的回文串最多只有∣S∣|S|∣S∣个 在这些回文串中,有一些是满足要求的,我们对这些串打上标记 首先跑一个ManacherManacherManacher,然后枚 ...
- 2019暑假杭电多校第6场签到题-1008-TDL
题目传送门 思路: 估计出n的范围,暴力就完事. 异或就是不进位的加法 (f(n,m) - n)^n == k, f(n,m)-n==k^n; 因为灯饰右边估计不会超过1e3,所以k^n<=1e ...
- 树形dp ---- 2018年杭电多校第二场 H travel
题目大意: 就是给你一个带点权的树,找到3条独立互不相交的路径使得权值和最大 解题思路: 很经典的树形dp 我们设dp[root][j][k]dp[root][j][k]dp[root][j][k]表 ...
- 杭电多校第一场第三题 Backpack(异或dp+bitset)
问题描述 爱丽丝有一个容量背包m她现在想用一些物品填充! 爱丽丝有n项目,每个项目都有一个卷v我和值w我. 是否可以从n个项目中选择多个项目,以使背包完全装满(即体积的总和等于背包容量)?如果是这样, ...
- 2022 杭电多校 第一场
文章目录 1011 Random 1012 Alice and Bob 1003 Backpack 1002 Dragon slayer 1009 Laser 1011 Random 签到 求一下期望 ...
- 2022杭电多校第一场
A String 题意:求s串1-i(1 <i <n)子串的贡献,贡献为公共前后缀相交并且相交部分长度为k的倍数的数量 题解做法是用exkmp求出s串与所有后缀的LCP后,设LCP为x,那 ...
最新文章
- Mybatis 使用的 9 种设计模式,真是太有用了
- android功能网格布局,Visual Studio 开发安卓之布局-网格布局(GridLayout)
- PAT甲级1029 Median:[C++题解]贪心、二路归并
- qhfl-9 微信模板消息推送
- v-for指令案例详解
- Android 常见错误
- mysql自带客户端连接服务器,客户端连接mysql服务器的指令 mysql -u root -p 详细讲解及使用实例...
- win10+linux系统进入安全模式,Win10进入安全模式的方法
- showdialog url访问页面_URL的优化方法
- 趣图:SQL 版的喝椰汁,没想到吧
- 剑指 offer set 8 树的子结构
- 机器码、序列号、认证码、注册码的生成算法(四)
- 京东店铺所有商品API接口(JD整店商品查询API接口)
- 一文读懂SpringBoot定时任务
- pyinstaller第三方库打包文件“ValueError”:找不到文件
- 推荐|从云生物科技行业数据安全解决方案
- 通俗理解深度学习梯度累加(Gradient Accumulation)的原理
- SEO是什么意思?seo入门者必读
- 理解OAuth 2.0 - 阮一峰的网络日志
- 每日一解 电话号码的字母组合
热门文章
- Xilinx SDK 中 的 'No rule to make target ' / '没有规则可以创建...'
- python亲和性分析_数据挖掘入门系列教程(一)之亲和性分析
- android 微信高仿,Android高仿微信聊天界面代码分享
- mysql语句将两列合并一列_mysql – SQL选择将两列合并为一列
- 利用python计算个人所得税
- 【论文笔记】:CornerNet: Detecting Objects as Paired Keypoints
- Flink学习1——运行时架构(standalone模式)
- java sql语句之插入语句的拼接规则
- springboot游泳池管理系统
- [程序人生]--人生架构三个层次:智慧是大脑,选择是躯干,知识文化是血肉