Codeforces 题目传送门 & 洛谷题目传送门

题目名称 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+状态设计)的更多相关文章

  1. 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)

    根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...

  2. 教主泡嫦娥[有趣的dp状态设计]

    P1342 教主泡嫦娥 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国 ...

  3. Dp状态设计与方程总结

    1.不完全状态记录<1>青蛙过河问题<2>利用区间dp 2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问 ...

  4. Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性

    https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...

  5. 关于一类容斥原理设计 dp 状态的探讨

    写在前面 为什么要写?因为自己学不明白希望日后能掌握. 大体思路大概是 设计一个容斥的方案,并使其贡献可以便于计算. 得出 dp 状态,然后优化以得出答案. 下列所有类似 \([l,r]\) 这样的都 ...

  6. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  7. codeforces 691E 矩阵快速幂+dp

    传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...

  8. codeforces 149D Coloring Brackets (区间DP + dfs)

    题目链接: codeforces 149D Coloring Brackets 题目描述: 给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的. 1,每个括号只有三种选择:涂红 ...

  9. dp状态压缩

    dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...

随机推荐

  1. 百度OCR技术博客

    百度OCR工具链使用 百度OCR的API使用总体来说比较容易,主要步骤为:注册云平台并登录,选择服务并创建应用,保存API Key以及Secret Key,选择调用API. 注册登录百度云平台 首先需 ...

  2. 【二食堂】Beta - Scrum Meeting 4

    Scrum Meeting 4 例会时间:5.17 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 继续完成文本区域划词添加的功能 issue 1. 划词功能已经实现,继续开发 ...

  3. Ruby on Rails 单元测试

    Ruby on Rails 单元测试 为什么要写测试文件? 软件开发中,一个重要的环节就是编写测试文件,对代码进行单元测试,确保程序各部分功能执行正确.但是,这一环节很容易被我们轻视,认为进行单元测试 ...

  4. 2020BUAA软工提问回顾和个人总结作业

    2020BUAA软工提问回顾和个人总结作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾和个人总结作业 我在 ...

  5. The entitlements specified in your application’s Code Signing Entitlements file do not match those s

    今天给打包 TPshop IOS (搜豹商城) ipa文件 调试运行 xcode运行提示这个错误: The entitlements specified in your application's C ...

  6. Python gpu 显卡小工具 gpu

    安装 pip install gpustat 或者 换源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade gpust ...

  7. axios & fetch 异步请求

    // 一.创建实例 const request = axios.create({ baseURL: "http://kg.zhaodashen.cn/v2", headers: { ...

  8. HTML 简单介绍

    1.什么是HTML > HTML是用来描述网页的一种语言 > HTML指的是超文本标记语言(Hyper Text Markup Language) > 标记语言是一套标记标签(mar ...

  9. electron获取不到remote

    electron获取不到remote 问题 // 渲染进程 let remote = require('electron').remote console.log(remote) // undefin ...

  10. 1.在项目中使用D3.js

    在项目中使用D3.js D3.js(全称:Data-Driven Documents)是一个基于数据操作文档的JavaScript库.D3帮助您使用HTML.SVG和CSS使数据生动起来.D3对web ...