HDU 6578 Blank
Time limit 1000 ms
Memory limit 262144 kB
OS Windows
Source 2019 Multi-University Training Contest 1
感想
火车上AK这场比赛的dls,在两天后直播讲题,讲到这题的时候,说得好轻松啊,一个简单的dp就完事了,然后说了一下dp的参数,然后就到下一题了……
解题思路
扔几个链接,融会贯通一下
- https://blog.csdn.net/m0_43448982/article/details/96988882
 - https://blog.csdn.net/Ratina/article/details/97237438
 - https://www.cnblogs.com/zhuyou/p/11273721.html
 
大概就是设\(dp[x][y][z][i]\)代表如下的意思:从前向后扫,扫到目前第\(i\)个格子时,4种颜色最后出现的位置分别为\(x、y、z、i\)时的方案数,其中\(x\leqslant y\leqslant z\leqslant i\),在\(x、y、z、i\)为0时取等号,表示目前有一些颜色还没有出现,即最后一次出现的位置为0。
颜色种类不重要,因为计算过程已经把不同颜色的组合方式计算进去了,重要的是颜色的。然后染这一格(\(i\))的时候的方案数是从染上一个格子(\(i-1\))的方案数转移过来的。
扩展当前这一个格子的时候,我们可以取之前出现过的4种颜色中的一种。举个例子,假设我们取的是之前最后一次出现在\(x\)的那个颜色,那么会发生这样的转移——\(dp[y][z][i-1][i]+=dp[x][y][z][i-1]\)(想想dp数组四个参数的含义和大小关系,现在这个状态的数量增加了上一个状态的数量那么多种),取的是最后一次出现在\(y\)的那个颜色的话,发生的转移就是——\(dp[x][z][i-1][i]+=dp[x][y][z][i-1]\),同样的道理还有\(dp[x][y][i-1][i]+=dp[x][y][z][i-1]\)和\(dp[x][y][i-1][i]+=dp[x][y][z][i]\)。对于判断条件,当我们跑完第\(i\)个格子的时候,就检查以\(i\)为右端点的所有条件,对于一个条件——\([l,r]\)之间有\(x\)种颜色,我们可以看那些状态是否满足条件,看每个颜色最后一次出现的位置在区间内还是区间外,然后根据这个统计区间内颜色数量,不满足条件就把它们清零,防止转移到下一个\(i\)。
统计的时候就统计所有\(i=n\)的格子,把数量加起来就好。但是这种方法会爆空间,注意到\(i\)那一维可以滚动,所以把\(i\)那一维滚动起来。另外注意取模 993244853 998244353。
源代码
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int mod=998244353;
int T;
int n,m;
long long dp[105][105][105][2];
//x<y<z<i
struct Condition{
	int l,x;
};
std::vector<Condition> c[105];
int main()
{
	//freopen("test.in","r",stdin);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<105;i++) c[i].clear();
		for(int i=1,l,r,x;i<=m;i++)
		{
			scanf("%d%d%d",&l,&r,&x);
			c[r].push_back({l,x});
		}
		dp[0][0][0][0]=1;
		int cur=1;//i&1
		int last=0;//!(i&1)
		for(int i=1;i<=n;i++)
		{
			for(int z=0;z<=i;z++)
			{
				for(int y=0;y<=z;y++)
				{
					for(int x=0;x<=y;x++)
					{
						dp[x][y][z][cur]=0;//清零
					}
				}
			}
			for(int z=0;z<i;z++)
			{
				for(int y=0;y<=z;y++)
				{
					for(int x=0;x<=y;x++)//转移
					{
						long long temp=dp[x][y][z][last];
						dp[x][y][z][cur]+=temp;
						dp[y][z][i-1][cur]+=temp;
						dp[x][z][i-1][cur]+=temp;
						dp[x][y][i-1][cur]+=temp;
						dp[x][y][z][cur]%=mod;
						dp[y][z][i-1][cur]%=mod;
						dp[x][z][i-1][cur]%=mod;
						dp[x][y][i-1][cur]%=mod;
					}
				}
			}
			for(unsigned int cc=0;cc<c[i].size();cc++)//判断
			{
				for(int z=0;z<i;z++)
					for(int y=0;y<=z;y++)
						for(int x=0;x<=y;x++)
						{
							int temp=1+(x>=c[i][cc].l?1:0)+(y>=c[i][cc].l?1:0)+(z>=c[i][cc].l?1:0);//统计区间内颜色数量
							if(temp!=c[i][cc].x) dp[x][y][z][cur]=0;
						}
			}
			std::swap(cur,last);
		}
		long long ans=0;
		for(int z=0;z<n;z++)//统计答案
		{
			for(int y=0;y<=z;y++)
			{
				for(int x=0;x<=y;x++)
				{
					ans+=dp[x][y][z][last];
					ans%=mod;
				}
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}
												
											HDU 6578 Blank的更多相关文章
- HDU - 6578 Blank DP + 滚动数组
		
HDU - 6578 Blank 题意 给你\(\{0,1,2, 3\}\)四个数,分别填入长度为\(n\)的数列中,有\(m\)个限制条件,\(l_{i}, r_{i}, x_{i}\)表示在\([ ...
 - [2019HDU多校第一场][HDU 6578][A. Blank]
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 题目大意:长度为\(n\)的数组要求分别填入\(\{0,1,2,3\}\)四个数中的任意一个,有 ...
 - HDU 3572 Task Schedule(拆点+最大流dinic)
		
Task Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
 - hdu 1003  MAX SUM 简单的dp,测试样例之间输出空行
		
测试样例之间输出空行,if(t>0) cout<<endl; 这样出最后一组测试样例之外,其它么每组测试样例之后都会输出一个空行. dp[i]表示以a[i]结尾的最大值,则:dp[i ...
 - HDU 2274 Magic WisKey
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2274 Magic WisKey Time Limit: 2000/1000 MS (Java/Othe ...
 - HDU 1505 City Game (hdu1506  dp二维加强版)
		
F - City Game Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submi ...
 - HDU 1231 最大连续子序列 &&HDU 1003Max Sum    (区间dp问题)
		
C - 最大连续子序列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...
 - HDU 1707  简单模拟  Spring-outing Decision
		
Spring-outing Decision Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
 - HDU 1708   简单dp问题 Fibonacci String
		
Fibonacci String Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
 
随机推荐
- 【转】应用宝基于Robotium自动化测试
			
(转载:http://tmq.qq.com/2016/05/robotium_for_app_test/) 1 背景目的应用宝项目组采用FT(Feature Team)模式,整个项目组分为多个FT,而 ...
 - java 依据文件名判断mime类型
			
依据文件名称判断mime类型 import java.util.HashMap; import java.util.Map; /** * 依据文件名获取MimeType */ public class ...
 - Tomcat使用时出现的问题总结
			
1.有两种办法解决Tomcat启动时端口号冲突问题 1.第一种: 查看本地端口使用情况,找到被占用的8080端口,杀死该进程 1.查看本地端口命令:cmd->netstat -ano 2.找到 ...
 - Bug快到碗里来
			
Bug快到碗里来 python错误--'list' object is not callable 原因及解决方法1 你定义了一个变量的变量名和系统自带的关键字冲突,调用变量时关键字被传到调用的位置,就 ...
 - 解决IOS把数字渲染为电话号码,颜色为蓝色解决方案
			
可将telephone=no,则手机号码不被显示为拨号链接<meta name="format-detection" content="telephone=no&q ...
 - [React] react-interview-01
			
1.render 函数中 return 如果没有使用()会有什么问题? 我们在使用 JSX 语法书写 react 代码时,babel 会将 JSX 语法编译成 js,同时会在每行自动添加分号(:),如 ...
 - node(koa2)跨域与获取cookie
			
欲做一个node 的网关服务,通过 cookie 做信息传递,选择框架 koa2,这里简单记录跨域处理以及 cookie 获取. 首先:解决跨域问题,使用 koa2-cros 来处理,跨域问题后端处理 ...
 - 吴恩达深度学习:2.12向量化logistic回归
			
1.不使用任何for循环用梯度下降实现整个训练集的一步迭代. (0)我们已经讨论过向量化如何显著加速代码,在这次视频中我们会设计向量化是如何实现logistic回归,这样酒桶同时处理m个训练集,来实现 ...
 - redis常见问题和解决方案
			
转载:https://www.cnblogs.com/aspirant/p/6820262.html [原创]那些年用过的Redis集群架构(含面试解析) redis常见问题和解决方案 持久化.主从问 ...
 - 1.Java 字符分割
			
使用方法 性能比较 使用方法 或|,点.,加+,乘*,在字符串中出现时,如果这个字符串需要被split,则split时候,需要在前面加两个反斜杠. 与&,在split时候,不需要转义. 一.j ...