Codeforces 889E - Mod Mod Mod(dp+状态设计)
题目名称 hopping
我们记 \(x_i=X\bmod a_1\bmod a_2\bmod\dots\bmod a_i\),也就是 \(X\) 连续 mod 上前 \(i\) 个数后得到的结果。
一个非常 naive 的想法是设 \(dp_{i,j}\) 表示考虑到前 \(i\) 个数,当前的 \(x_i=j\) 的最大的 \(\sum\limits_{k=1}^ix_k\),显然有一个 \(\mathcal O(na_i)\) 的转移。但事实上稍微了解一下 \(dp\) 优化的同学都可用看出这个 \(dp\) 是没有前途的,因为这个状态本身就无法优化,每个 \(dp_{i,j}\) 都有可能对最终的 \(dp_n\) 产生贡献。
于是我们只好换个状态。首先可以观察到一个性质,就是若 \(x_i\ne 0\),那么若我们令 \(X\leftarrow X-1\) 一定有新的 \(x_i\) 等于原本的 \(x_i\) 减 \(1\),我们记 \(Y=\sum\limits_{j=1}^ix_j-x_i\),根据上面的推论可知,如果我们令 \(X\leftarrow X-x_i+v(v\in[0,x_i])\) 一定有 \(\sum\limits_{j=1}^ix_j=Y+vi\)。于是我们考虑将 \([0,j]\) 搞在一起转移。设 \(dp_{i,j}\) 为考虑到前 \(i\) 个数,当前的 \(x_i=j\) 的最大的 \(Y\)。考虑怎么转移,我们考虑枚举一个 \(k\) 并将 \(X\) 改为 \(X-x_i+k\),那么就有 \(dp_{i+1,k\bmod a_{i+1}}\leftarrow dp_{i,j}+(k-k\bmod a_{i+1})\times i\)(因为将 \(X\) 改为 \(X-x_i+k\) 之后,真实的 \(\sum\limits_{j=1}^ix_j=Y+ki\),\(\sum\limits_{j=1}^ix_j-(k\bmod a_{i+1})=Y+ki-i(k\bmod a_{i+1})=dp_{i,j}+(k-k\bmod a_{i+1})\times i\)),但显然我们不可能枚举 \(k\) 进行转移,考虑将 \([0,j]\) 中所有数 \(\bmod a_{i+1}\) 的值写成一排,若 \(j\ge a_{i+1}\) 那显然是若干个 \(0...a_{i+1}-1\) 的周期加一个零头,不难发现我们最优转移点只有两个,那就是最后一个周期的 \(a_{i+1}-1\),以及最后零头部分的最后一个数(\(j\bmod a_{i+1}\)),因为其他状态要么没有这两个状态来得优,要么可以通过这两个状态在未来的转移中得到,这个稍微想想就能想通;若 \(j<a_{i+1}\),与上面的情况也类似,只不过少了最后一个周期的 \(a_{i+1}-1\) 的情况。形式化地写下来就是以下状态转移方程:
\(a_{i+1,j}\leftarrow dp_{i,j}(j<a_{i+1})\)
\(a_{i+1,j\bmod a_{i+1}}\leftarrow dp_{i,j}+(j-j\bmod a_{i+1})\times i(j\ge a_{i+1})\)
\(a_{i+1,a_{i+1}-1}\leftarrow dp_{i+j}+(\lfloor\dfrac{j+1}{a_{i+1}}\rfloor\times a_{i+1}-a_{i+1})\times i(j\ge a_{i+1})\)
第一维可以直接去掉,第二维可以用 map
优化,注意到每个 \(j\) 最多转移 \(\log a_i\) 次,因此复杂度 \(n\log a_i\log n\),可通过此题。
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=2e5;
int n;ll a[MAXN+5];
map<ll,ll> dp;
int main(){
scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
dp[a[1]-1]=0;
for(int i=1;i<n;i++){
for(map<ll,ll>::iterator it=dp.lower_bound(a[i+1]);it!=dp.end();it++){
ll x=it->fi,y=it->se;
dp[x%a[i+1]]=max(dp[x%a[i+1]],y+1ll*i*(x-x%a[i+1]));
dp[a[i+1]-1]=max(dp[a[i+1]-1],y+1ll*i*((x+1)/a[i+1]*a[i+1]-a[i+1]));
} dp.erase(dp.lower_bound(a[i+1]),dp.end());
} ll ans=0;
for(map<ll,ll>::iterator it=dp.begin();it!=dp.end();it++){
ll x=it->fi,y=it->se;chkmax(ans,y+x*n);
} printf("%lld\n",ans);
return 0;
}
Codeforces 889E - Mod Mod Mod(dp+状态设计)的更多相关文章
- 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)
根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...
- 教主泡嫦娥[有趣的dp状态设计]
P1342 教主泡嫦娥 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国 ...
- Dp状态设计与方程总结
1.不完全状态记录<1>青蛙过河问题<2>利用区间dp 2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问 ...
- Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性
https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...
- 关于一类容斥原理设计 dp 状态的探讨
写在前面 为什么要写?因为自己学不明白希望日后能掌握. 大体思路大概是 设计一个容斥的方案,并使其贡献可以便于计算. 得出 dp 状态,然后优化以得出答案. 下列所有类似 \([l,r]\) 这样的都 ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- codeforces 691E 矩阵快速幂+dp
传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...
- codeforces 149D Coloring Brackets (区间DP + dfs)
题目链接: codeforces 149D Coloring Brackets 题目描述: 给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的. 1,每个括号只有三种选择:涂红 ...
- dp状态压缩
dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...
随机推荐
- 欧姆龙plc通讯协议格式
欧姆龙CPM1A型plc与上位计算机通信的顺序是上位机先发出命令信息给PLC,PLC返回响应信息给上位 机.每次通信发送/接受的一组数据称为一"帧".帧由少于131个字符的数据构成 ...
- linux centos7 修改默认网卡命名规则为eth0脚本
CentOS6之前基于传统的命名方式如:eth1,eth0.... Centos7提供了不同的命名规则,默认是基于固件.拓扑.位置信息来分配.这样做的优点是命名是全自动的.可预知的,缺点是比eth0. ...
- 关于下载pyton第三方库的细节
1.下载Python第三方库有时候国外的网站网速很不好,需要选择国内的镜像网站去下载 阿里云 http://mirrors.aliyun.com/pypi/simple 中国科技大学 https: ...
- java实现rsa加密算法【5min快速应用教程】
该篇文章的主要目的是让读者能够迅速应用到项目中,想要了解详细的rsa加密算法的,可以百度找到更多原理.深度分析的文章. RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一 ...
- kail入侵win2003 sp2 中文版系统
攻击机:kail -- IP:192.168.74.132 目标靶机:win2003 sp2 中文版系统-- IP:192.168.74.128 一.扫描漏洞 1. 在kail中运行 namp 192 ...
- (转)刚来的大神彻底干掉了代码中的if else...
一旦代码中 if-else 过多,就会大大的影响其可读性和可维护性. 首先可读性,不言而喻,过多的 if-else 代码和嵌套,会使阅读代码的人很难理解到底是什么意思.尤其是那些没有注释的代码. 其次 ...
- typedef的用法 单向链表的查找、增加、删除、销毁。
一:typedef的用法. 写一个数据结构(计算机存储数据的一种方式,是抽象的,可以人为组织,提高算法效率),我们需要注意:接口友好,模块化,规范命名等方面,在接口友好方面,typedef是非常 ...
- Win10-更改c盘下的用户文件夹名
如果你是win10家庭版,请先升级成专业版 win10家庭版升级到win10专业版 修改用户名称
- win10 vscode安装babel
第一步:安装 babel-cli cd进入项目根目录,执行命令: npm install --global babel-cli 第二步:检测第一步是否成功,输入命令 babel --version,若 ...
- buuoj刷题 October
2019 极客大挑战 web easysql 直接万能密码登就完事了 LoveSQL 万能密码登进去,给了md5,没解出来 手注吧,都要忘了手注怎么注了 猜字段数 3的时候正常不报错 看回显位,2,3 ...