题目链接:http://codeforces.com/contest/1140/problem/E

题目大意:

如果一个数组的存在一个奇数长的回文就不好。

不是不好的数组是好的。

你可以把-1用1到k中一个数替换。问可以有多少种不同的好数组。

开虚拟赛最后一分钟把它A了,很开心,很开心。

思路:

我们翻译一下,如果存在长度为5的回文就必须会出现长度为3的回文。

也就是说不能出现长度为3回文。

也就是说x[i]!=x[i+2],x[i]!=x[i-2];(x[i]为输入数组)

那我们把数组分为两个数组,按奇偶分。(1,3,5,,,)(2,4,6,,,)

这两个数组就都要满足一个条件x[i]!=x[1+i]&&x[i]!=x[i-1];(相邻两个数不能相等)

然后我们就开始DP啦。

对于奇偶两个数组我就分析一个啦,因为都差不多。(相邻两个数不能相等)

首先,当然是n*k的DP。

DP[a][b]表示到a下为b的方案数。

所以DP[a][b]等于所有DP[a-1][i](1<=i<=k,i!=b)的和。

如果x[a]为-1,就算所有的1到k。

如果x[a]>0,就只算DP[a][x[a]];

这个可以理解吗?

可以理解就太好了!!!

然而,你在DP的过程中,发现DP[a][i](1<=i<=k)中只可能有两个不同的值(不会超过3个),而且产生不同的值是一个特殊的位置。

你可以先拿小一点的数据打表看看。

也就是说,对于每一个状态。只有两种可能,而不是k种可能。

所以,我们就可以写O(n)的DP了。

我画了两张图给你们看看。

然后到了愉快的贴代码时间了。不是很懂可以私聊QQ:1328247116,也可以下面留言。~~

#include <bits/stdc++.h>
using namespace std; #define int long long
#define IOS ios::sync_with_stdio(false);
#define endl "\n"
#define MAX 200050
#define mod 998244353 ///
int x[MAX];
int dp[MAX];
int dp_1=,dp_1_sum=;
int dp_2=,dp_2_sum=;
int ans[MAX];
///
signed main()
{
IOS; int n,m;
cin>>n>>m;
for(int i=;i<=n;i++){
cin>>x[i];
} if(x[]>){
dp[]=;
dp_1=x[],dp_1_sum=;
}
else{
dp[]=;
dp_1=,dp_1_sum=;
} for(int i=;i<=n;i+=){
if(x[i]>){
if(x[i]==dp_1){
dp_1_sum=(m-)*dp[i-]%mod;
}
else{
dp_1_sum=((m-)*dp[i-]%mod+dp_1_sum)%mod;
}
dp_1=x[i];
}
else{
dp[i]=((m-)*dp[i-]%mod+dp_1_sum)%mod;
dp_1_sum=(m-)*dp[i-]%mod;
}
} ///
if(x[]>){
dp[]=;
dp_2=x[],dp_2_sum=;
}
else{
dp[]=;
dp_2=,dp_2_sum=;
} for(int i=;i<=n;i+=){
if(x[i]>){
if(x[i]==dp_2){
dp_2_sum=(m-)*dp[i-]%mod;
}
else{
dp_2_sum=((m-)*dp[i-]%mod+dp_2_sum)%mod;
}
dp_2=x[i];
}
else{
dp[i]=((m-)*dp[i-]%mod+dp_2_sum)%mod;
dp_2_sum=(m-)*dp[i-]%mod;
}
}
int ans;
if(n%==){
ans=(dp_1_sum+(m-)*dp[n-]%mod)*(dp_2_sum+(m-)*dp[n]%mod)%mod;
}
else{
ans=(dp_1_sum+(m-)*dp[n]%mod)*(dp_2_sum+(m-)*dp[n-]%mod)%mod;
}
cout<<ans;
return ;
} /* */

codeforces 1140E Palindrome-less Arrays的更多相关文章

  1. Codeforces 486C Palindrome Transformation(贪心)

    题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N.指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:事实上仅仅要 ...

  2. codeforces 486C. Palindrome Transformation 解题报告

    题目链接:http://codeforces.com/problemset/problem/486/C 题目意思:给出一个含有 n 个小写字母的字符串 s 和指针初始化的位置(指向s的某个字符).可以 ...

  3. Codeforces 335B Palindrome

    http://codeforces.com/contest/335/problem/B 题意:  给定一个长度不超过5*10^4的只包含小写字母的字符串,要求你求它的回文子序列,如果存在长度为100的 ...

  4. Codeforces 159D Palindrome pairs

    http://codeforces.com/problemset/problem/159/D 题目大意: 给出一个字符串,求取这个字符串中互相不覆盖的两个回文子串的对数. 思路:num[i]代表左端点 ...

  5. Codeforces 932G Palindrome Partition - 回文树 - 动态规划

    题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$ ...

  6. Codeforces 915 G Coprime Arrays

    Discipntion Let's call an array a of size n coprime iff gcd(a1, a2, ..., an) = 1, where gcd is the g ...

  7. codeforces 486C Palindrome Transformation 贪心求构造回文

    点击打开链接 C. Palindrome Transformation time limit per test 1 second memory limit per test 256 megabytes ...

  8. CodeForces 486C Palindrome Transformation 贪心+抽象问题本质

    题目:戳我 题意:给定长度为n的字符串,给定初始光标位置p,支持4种操作,left,right移动光标指向,up,down,改变当前光标指向的字符,输出最少的操作使得字符串为回文. 分析:只关注字符串 ...

  9. Codeforces 932G Palindrome Partition 回文树+DP

    题意:给定一个串,把串分为偶数段 假设分为$s_1,s_2,s_3....s_k$ 求满足$ s_1=s_k,s_2=s_{ k-1 }... $的方案数模$10^9+7$ $|S|\leq 10^6 ...

随机推荐

  1. Java并发编程--2.synchronized

    前言 synchronized关键字是互斥锁,也称为内部锁 每个对象都有自己的monitor(锁标记),它是为了分配给线程,最多一个线程可以拥有对象的锁 使用 synchronized修饰成员方法,锁 ...

  2. 【node.js】全局变量、常用工具、文件系统

    学习链接:http://www.runoob.com/nodejs/nodejs-global-object.html 在 JavaScript 中,通常 window 是全局对象, 而 Node.j ...

  3. JSP九大内置对象和四大作用域和Servlet的三大作用域对象

    一.JSP九大内置对象:内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用 内置对象特点: 由JSP规范提供,不用编写者实例化. 通过Web容器实现和管理 所有 ...

  4. pip问题解决方案

    错误信息:usr/bin/pip: No such file or directory 解决办法(一共四步,按照下面的步骤来从1到4,最后你会发现问题都解决了): 1.which pip /usr/l ...

  5. python自动化之上传文件的3种方法和图片预览

    ajax上传文件的三种方法 第一种xhr提交 function xhrSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementBy ...

  6. Vue2.5开发去哪儿网App 从零基础入门到实战项目

    第1章 课程介绍本章主要介绍课程的知识大纲,学习前提,讲授方式及预期收获. 1-1 课程简介 试看第2章 Vue 起步本章将快速讲解部分 Vue 基础语法,通过 TodoList 功能的编写,在熟悉基 ...

  7. 利用SimpleDateFormat进行时间的跨时区转换 - Java

    * 次方法主要用来将特定时区的时间转换成指定时区的时间,比如将北京时间“2018-04-08 15:40:49.031”,转换对应的美国东部时间是“2018-04-08 03:40:49.031”   ...

  8. 很清晰的解读i2c协议

    很清晰的解读i2c协议 转载:http://dpinglee.blog.163.com/blog/static/14409775320112239374615/ 1.I2C协议 2条双向串行线,一条数 ...

  9. Cloudera Manager Server CDH 5.15部署

    安装前准备 主机和系统 Host OS Memory IP bigdata001-dev Cent OS 7.4 x64 32G 192.168.1.1 bigdata002-dev Cent OS ...

  10. Python学习之迭代器和生成器

    那么首先什么是迭代器和生成器呢? 迭代器即迭代的工具,那么什么又是迭代呢?所谓迭代:迭代是一个重复的过程,每次重读即一次迭代,并且每次迭代的结果都是下一次迭代的初始值.例: l=[1,2,3] cou ...