【数位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位置的代价,这样显然有一些是不优的,然 ...
随机推荐
- 提交并发量的方法:Java GC tuning :Garbage collector
三色算法,高效率垃圾回收,jvm调优 Garbage collector:垃圾回收器 What garbage? 没有任何引用指向它的对象 JVM GC回收算法: 引用计数法(ReferenceCou ...
- JS基础回顾_滚动条
// log function getScrollOffset() { if (window.pageXOffset) { return { x: window.pageXOffset, y: win ...
- PicGo软件搭配gitee实现图床
1.安装PicGo软件,并配置gitee 1.1安装picGo picGo 安装gitee-uploader 插件 官网下载地址如下:最新版本 可以自行选择版本进行下载,这里我选择了最新的版本进行下载 ...
- lua数据结构之table的内部实现
一.table结构 1.Table结构体 首先了解一下table结构的组成结构,table是存放在GCObject里的.结构如下: typedef struct Table { CommonH ...
- python3 while循环
python不支持n++这样格式,因为python中变量不像c那样事先定义好变量类型,在内存中开辟指定的空间,然后赋值. python中以字符串为例,事先在内存划分空间来存放字符串,然后用变量名来指向 ...
- IHttpClientFactory组件使用
起因 :由于需要前段时间写了一个http请求的公共方法 使用的 HttpClient,但是在jmeter测试下 爆发了这个问题:“Cannot assign requested address Ca ...
- jekins使用的坑
1.日志打满 一个周末回来,服务器的磁盘就写满了 现象如下,最后是修改catalina脚本 添加了如下配置 ###jekins log problem#########export JAVA_OPTS ...
- 6.Kafka消息流处理
- Android动画系列之帧动画和补间动画
原文首发于微信公众号:jzman-blog,欢迎关注交流! Android 提供三种动画:帧动画.补间动画和属性动画,本篇文章介绍帧动画以及补间动画的使用,属性动画的使用将在后面的文章中分享,那就来复 ...
- Alink漫谈(二十二) :源码分析之聚类评估
Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...