【数位DP】SCOI2014 方伯伯的商场之旅
题目内容
方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。
说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 \(K\) 进制后的第 \(j\) 位。现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 \(L,R\)。
方伯伯要把位置在 \([L,R]\) 中的每个人的石子都合并成一堆石子。每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量 \(\times\) 移动的距离。
商场承诺,方伯伯只要完成任务,就给他一些椰子,代价越小,给他的椰子越多。所以方伯伯很着急,想请你告诉他最少的代价是多少。例如:10进制下的位置在12312的人,合并石子的最少代价为:1×2+2×1+3×0+1×1+2×2=9,即把所有的石子都合并在第三堆。
数据范围
\(1\leq L\leq R\leq 10^{15}\),\(2\leq K\leq 20\)
思路
感觉学了个假的数位 \(DP\)。
如果你做过这道题或者这道题的话可以想到选择石子位置的中位数一定是最优的。
但是本题对于并无卵用,因为无法同时处理很多数字,只能单个处理。(建议写暴力)
对于本题的时空限制来说显然枚举每个数是不现实的。但显然数位数不会很多,可以考虑枚举贪心,整体处理(前缀和的形式)。首先把第一个位置当作集合点,算出一个贡献。然后向右枚举,更新贡献。
可以看出这是一个单峰函数,当集合点右移的时候,如果新的答案更小,就更新答案,否则就不变。
举个栗子:把二号点转移到三号点,变动的就是:小于等于二号点的石子个数 \(-\) 大于等于三号点的石子个数。如果这个值是负的,我们就更新。
为什么贪心是正确的?因为前面的石子数量和一直在增加,而其后的一直在减小,因此答案的减小值一定是不断减小的。
先用一遍数位 \(DP\) 求出集合点在一号点的答案,然后向右枚举转移即可。当枚举到 \(n\) 的时候,这道题就做完了。
代码
不会真的有人数位 \(DP\) 写递推吧,不会吧不会吧不会吧。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int L,R,K;
int a[100],f[100][10000];
int dfs(int now,int sum,int p,int lim){
if(!now)return max(sum,0LL);//若减去的为负值,即新的答案更大,则不更新
if(!lim&&~f[now][sum])return f[now][sum];
int ans=0;
int num=lim?a[now]:K-1;
for(int i=0;i<=num;i++)
ans+=dfs(now-1,sum+(p==1?i*(now-1):(now<p?-i:i)),p,lim&&(i==num));
if(!lim)f[now][sum]=ans;
return ans;
}
inline int Solve(int x){
int n=0;
while(x){
a[++n]=x%K;
x/=K;
}
int ans=0;
for(int i=1;i<=n;i++){
memset(f,-1,sizeof(f));
ans+=(i==1?1:-1)*dfs(n,0,i,1);
}
return ans;
}
signed main(){
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
scanf("%lld%lld%lld",&L,&R,&K);
printf("%lld",Solve(R)-Solve(L-1));
return 0;
}
【数位DP】SCOI2014 方伯伯的商场之旅的更多相关文章
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 449 Solved: 254[Submit][Sta ...
- 洛谷P3286 [SCOI2014]方伯伯的商场之旅
题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅 思路 数位DP dalao说这是数位dp水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...
- BZOJ.3598.[SCOI2014]方伯伯的商场之旅(贪心 数位DP)
题目链接 先考虑,对于确定的一个数,怎样移动代价最少(或者移到哪个位置最优)? 假设我们都移到下标\(1\)位置(设集合点为\(1\)),那么移动到下标\(2\)与\(1\)相比代价差为:\(下标&l ...
- BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)
看到数据范围就可以猜到数位dp了.显然对于一个数最后移到的位置应该是其中位数.于是考虑枚举移到的位置,那么设其左边和为l,左右边和为r,该位置数为p,则需要满足l+p>=r且r+p>=l. ...
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- [SCOI2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- bzoj3598 [Scoi2014]方伯伯的商场之旅
数位dp,我们肯定枚举集合的位置,但是如果每次都重新dp的话会很麻烦,所以我们可以先钦定在最低位集合,dp出代价,然后再一步步找到正确的集合点,每次更改的代价也dp算就好了. #include < ...
- 【bzoj3598】 Scoi2014—方伯伯的商场之旅
http://www.lydsy.com/JudgeOnline/problem.php?id=3598 (题目链接) 题意 Solution 原来这就是极水的数位dp,呵呵= =,感觉白学了.htt ...
- bzoj 3598: [Scoi2014]方伯伯的商场之旅【数位dp】
参考了这个http://www.cnblogs.com/Artanis/p/3751644.html,好像比一般方法好写 大概思想就是先计算出把所有石子都合并到1位置的代价,这样显然有一些是不优的,然 ...
随机推荐
- Repeater每行绑定事件代码
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { Repea ...
- windows-android-appium环境搭建
一.安装jdk 安装jdk1.7以上版本,会生成一个jdk目录,和单独的jre目录(注意:不是jdk里面的jre,时安装过程中设置的那个jre路径)安装完成后并配置环境变量 在系统环境变量中,新建:J ...
- 图解 Await 和 Async
原文链接:Await and Async Explained with Diagrams and Examples 文章目录 简介 Promise 问题:组合 Promise Async 函数 Awa ...
- 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...
- Fiddler的基本界面介绍
前言 fiddler的界面,主要是分以下6个模块. 一:主菜单栏: 可以参考:https://www.cnblogs.com/sjl179947253/p/7620524.html 二:工具栏: 1. ...
- Jenkins+Git+Gitlab+Ansible实现持续集成自动化部署动态网站(7)
项目前言 在上一篇博客<Jenkins+Git+Gitlab+Ansible实现持续化集成一键部署静态网站(一)–技术流ken>中已经详细讲解了如何使用这四个工具来持续集成自动化部署一个静 ...
- 安装Linux的CentOS操作系统 - 初学者系列 - 学习者系列文章
Linux系统对于一些熟悉Windows操作系统的用户来说可能比较陌生,但是它也是一种多用户.多任务的操作系统,现在也发展成为了多种版本的操作系统了.如果想对该系统进行学习,请下载这个学习文档:htt ...
- c++中清空输入缓冲区的方法(做cf的时候炸了)
C/C++ 四种清空输入缓冲区的方法 比较实用的一种 char c; while(c=getchar()!='\n'); 或者是这种 cin.ignore(count,c); count代表要清除的字 ...
- JVM学习(五)对象的引用类型
一.引言 前面我们学习了JVM的垃圾回收机制,我们知道了垃圾回收是JVM的自发行为:虽然我们可以通过System.gc() 或Runtime.getRuntime().gc()进行显式调用垃圾回收 , ...
- gcc g++ 安装与配置 入门详解 - 精简归纳
gcc g++ 安装与配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 24 转载请注明出处!️ 目录 gcc g++ 安装与配置 入门详解 - 精简归纳 一.下载MinGW ...