由于每一个操作的逆操作都存在,可以看作将$a_{i}$全部变为0的代价

先考虑第一个问题,即对于确定的$a_{i}$如何处理

如果仅能用第2种操作,定义点$i$的代价为以$i$为左端点或以$i-1$为右端点的的操作数,考虑一个代价的意义,即改变$i-1$和$i$的差值,因此$ans\ge C\sum_{i=0}^{n}\frac{|a_{i}-a_{i+1}|}{2}$(每一个操作会被算两次)

(对应的方案只要确保每一次操作减少两对“相邻两数的差值”)

加入第1种操作,由于操作与顺序无关,不妨先使用第1种操作、后使用第2种操作,假设第1种操作产生的序列为$b_{i}$,则答案为$C\sum_{i=0}^{n}|b_{i}-b_{i+1}|+\sum_{i=1}^{n}|a_{i}-b_{i}|$(换言之,即找到任意$b_{i}$,最小化该值)

令$f[i][j]$表示前$i$个数$b_{i}=j$的最小值,转移为$f[i][j]=\min(f[i-1][k]+|k-j|\times C)+2|a_{i}-j|$(这里都乘了2避免小数)

归纳$f[i][j]$具有凸性,转移可以看作找到斜率绝对值大于等于$C$的部分(由于凸性,斜率单调递增,即前后两个区间),将这一部分斜率对$\pm C$取max或min

同时,这也就证明了忽略$2|a_{i}-j|$后$f[i][j]$也具有凸性,而后者具有凸性,因此和也有凸性

我们直接维护斜率,更严谨的,令$f'[i][j]=f[i][j]-f[i][j-1]$,每一次转移相当于执行以下操作:1.将所有数对$-C$取max,对$C$取min;2.对$[1,a_{i}]$区间减2,对$(a_{i},+\infty)$区间加2

对于$f[i][0]$直接考虑上面的转移,即$f[i][0]=2a_{i}+\min_{k}f[i-1][k]+kC$

简单化简,有$f[i][0]=2a_{i}+f[i-1][0]+\min_{k}\sum_{j=1}^{k}f'[i-1][j]+C$,而由于$f'[i-1][j]+C$单调递增,后者也可以看作$\sum_{j}\min(f'[i-1][j]+C,0)$

答案即求$f[n+1][0]$,可以看作不断累加,即要求出每一次后面的式子对答案的贡献

由于位置之间相互独立,可以单独去算每一个数的贡献,先对区间离散化(对于$(a_{i-1},a_{i}]$这个区间的贡献显然都相同),再用$dp[i][j]$表示经过前$i$个点后值为$j$的方案数,复杂度为$o(n^{2}k^{2}C)$

再进一步的,只关心$a_{i}$与枚举的位置的关系,因此可以降为$o(n^{2}kC)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 105
4 #define mod 1000000007
5 vector<pair<int,int> >v;
6 int n,c,k,x,ans,mi[N],sz[N],sf[N],f[N][N];
7 int main(){
8 scanf("%d%d%d",&n,&c,&k);
9 mi[0]=1;
10 for(int i=1;i<=n;i++)mi[i]=1LL*mi[i-1]*k%mod;
11 for(int i=1;i<=n;i++)
12 for(int j=1;j<=k;j++){
13 scanf("%d",&x);
14 v.push_back(make_pair(x,i));
15 ans=(ans+x)%mod;
16 }
17 ans=2LL*ans*mi[n-1]%mod;
18 sort(v.begin(),v.end());
19 for(int i=1;i<=n;i++)sf[i]=k;
20 for(int i=-1,nex=0;i<(int)v.size();i=nex){
21 while ((i>=0)&&(nex<v.size())&&(v[nex].first==v[i].first)){
22 sz[v[nex].second]++;
23 sf[v[nex++].second]--;
24 }
25 x=v[nex].first;
26 if (i>=0)x-=v[i].first;
27 memset(f,0,sizeof(f));
28 f[0][2*c+2]=1;
29 for(int j=0;j<=n;j++)
30 for(int l=0;l<=2*c+4;l++){
31 if (l<2)ans=(ans+1LL*x*(mod+l-2)%mod*f[j][l]%mod*mi[n-j])%mod;
32 int ll=min(max(l,2),2*c+2);
33 f[j+1][ll+2]=(f[j+1][ll+2]+1LL*sz[j+1]*f[j][l])%mod;
34 f[j+1][ll-2]=(f[j+1][ll-2]+1LL*sf[j+1]*f[j][l])%mod;
35 }
36 }
37 ans=1LL*ans*(mod+1)/2%mod;
38 printf("%d",ans);
39 }

[atAGC049E]Increment Decrement的更多相关文章

  1. STL——increment/decrement/dereference操作符

    increment/dereference操作符在迭代器的实现上占有非常重要的地位,因为任何一个迭代器都必须实现出前进(increment,operator++)和取值(dereference,ope ...

  2. increment/decrement/dereference

    #include <vector> #include <deque> #include <algorithm> #include <iostream> ...

  3. 【M6】区别increment/decrement操作符的前置(prefix)和后置(postfix)形式

    1.考虑++(--的情况是一样的),前置是累加然后取出,后置是取出然后累加. 2.重载方法根据形参表的不同区分,问题来了,前置和后置形式都没有形参,因此没法区分.怎么办? 对于后置增加一个形参int, ...

  4. increment/decrement/dereference操作符

    标题以上分别对于++/--/* #include <iostream> #include <cstddef> using namespace std; class INT { ...

  5. chrome快捷键

    常用的为: Ctrl + ]   下一个面板 Ctrl + [   上一个面板 Ctrl + Alt + [ 去上一个历史记录的面板Ctrl + Alt + ]      去下一个历史记录的面板 Ct ...

  6. vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...

  7. Redis 对比 Memcached 并在 CentOS 下进行安装配置

    了解一下 Redis Redis 是一个开源.支持网络.基于内存.键值对的 Key-Value 数据库,使用 ANSI C 编写,并提供多种语言的 API ,它几乎没有上手难度,只需要几分钟我们就能完 ...

  8. 移动web 公用样式

    /*! normalize.css v3.0.2 | MIT License | github.com/necolas/normalize */ /** * 1. Set default font f ...

  9. Mifare系列5-存储结构(转)

    文/闫鑫原创转载请注明出处http://blog.csdn.net/yxstars/article/details/38081521 Mifare S50把1K字节的容量分为16个扇区(Sector0 ...

随机推荐

  1. 题解 Weak in the Middle

    题目传送门 Description 有一个长度为 \(n\) 的序列 \(a_{1,2,...,n}\) ,每次可以删掉 \(a_i\),当 \(\min(a_{i-1},a_{i+1})>a_ ...

  2. 题解 Wide Swap

    题目传送门 题目大意 给出一个长度为 \(n\) 的排列 \(a_{1,2,...,n}\) 以及常数 \(k\),每次可以交换两个数 \(a_i,a_j\) 当且仅当 \(j-i\ge k \tex ...

  3. SpringBoot入门01-环境部署

    随笔目录: 环境准备 创建过程 编码试行 环境准备 如果编辑器是还没有配置过相关环境的,在用SpringBoot开发项目的时候,需要先环境,spring boot官网建议的开发工具是: STS或Ide ...

  4. [spring-rabbit]自动配置原理

    1 一个简单的示例 在Spring Boot项目中使用spring-rabbit时,需要经过以下几个步骤: 引入依赖. 配置基本连接信息. 创建消息发布者,并发送消息. 创建消息消费者,监听消息并处理 ...

  5. nginx搭建网站踩坑经历

    为了更好的阅读体验,请访问我的个人博客 前言 早上刷抖音刷到一个只需要三步的nginx搭建教程(视频地址),觉得有些离谱,跟着复现了一遍,果然很多地方不严谨并且省略了大量步骤,对于很多不了解linux ...

  6. 【java】关键字this怎么用?

    摘至:https://www.php.cn/java/guide/462643.html java中this关键字的用法:1.当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中 ...

  7. Noip模拟54 2021.9.16

    T1 选择 现在发现好多题目都是隐含的状压,不明面给到数据范围里,之凭借一句话 比如这道题就是按照题目里边给的儿子数量不超过$10$做状压,非常邪门 由于数据范围比较小,怎么暴力就怎么来 从叶子节点向 ...

  8. Linux C语言多线程编程实例解析

    Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...

  9. STM32 学习笔记之中断应用概览--以f103为例

    异常类型 F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断.其中系统异常有8 个(如果把Reset 和HardFault 也算上的话就是10 个),外部中断有60个.除 ...

  10. Django 开发------django-crontab实现服务端的定时任务

    一.需求: 想实现类似 Linux 中crontab 的功能.定时执行计划任务. 二.配置: a.安装插件: # pip3 install django-crontab b.在settings.py ...