[SCOI2014]方伯伯的商场之旅
Description
Input
HINT
1 < = L < = R < = 10^15, 2 < = K < = 20
Solution
说白了,这个题就是给了L~R的数,每个数的每个数位是一堆石子,把这堆石子合成一个位置,求总的最小代价。
法一:GZZ法
发现,对于一个数字P,假设钦定最终合并位置是p,
调整的时候,p向左移动一位,代价变化是p及右边所有的数位和-p左边所有数位和。
p向右移动一位,代价变化是p及左边所有数位和-p右边所有数位和。
设最优的位置的数字是x,位置是p,p左边数位和是a,右边是b
那么,一定有不等式:x+a-b>=0 ; x+b-a>=0 就是说,x不论往左往右移动,代价的变化总是增大的。
即:-x<=a-b<=x
所以,如果知道最终填的a-b,和x,p,就可以判断这个p位置填x是不是左边a,右边b的最优解了。
枚举p,x;
伪代码:(cnt是最高位,进制用m,填数用k)
for(p=1~cnt)
for(x=0~m-1)
for(i=cnt~1)
for(a-b=-200~+200)
设f[i][a-b][0/1]表示,填完第i位,a-b的值,有没有限制情况下,所有符合情况的数移动到p位置所花费的代价。
g[i][a-b][0/1]表示,f的方案数,即满足情况的数的个数,方便转移。
if(i==p){
continue;
}
for(k=0;k<m;k++){
if(i<p)
else
}
在i循环完之后,
for(a-b=-200~+200)
if(-x<=a-b<x) ret+=f[1][a-b][0/1]
注意这里是<=和<,因为可能一个数字有两个位置都是最优的合并位置,只能算一遍。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
const int M=;
const int fix=;
const int up=;
ll f[N][][];
ll g[N][][];
ll L,R;
int m;
ll ansl,ansr;
int a[N],cnt;
ll wrk(){
ll ret=;
for(int p=;p<=cnt;p++){
for(int x=;x<m;x++){
memset(f,,sizeof f);
memset(g,,sizeof g);
g[cnt+][fix][]=;
for(int i=cnt;i>=;i--){
for(int j=;j<=up;j++){
if(i==p){
if(x<a[i]){
if(g[i+][j][]) g[i][j][]+=g[i+][j][],f[i][j][]+=f[i+][j][];
if(g[i+][j][]) g[i][j][]+=g[i+][j][],f[i][j][]+=f[i+][j][];
}
else if(x==a[i]){
g[i][j][]+=g[i+][j][],f[i][j][]+=f[i+][j][];
g[i][j][]+=g[i+][j][],f[i][j][]+=f[i+][j][];
}
else{
g[i][j][]+=g[i+][j][],f[i][j][]+=f[i+][j][];
}
continue;
} for(int k=;k<m;k++){
if(i>p){//before
if(j+k>up) continue; if(k<a[i]){
g[i][j+k][]+=g[i+][j][],f[i][j+k][]+=f[i+][j][]+(i-p)*k*g[i+][j][];
g[i][j+k][]+=g[i+][j][],f[i][j+k][]+=f[i+][j][]+(i-p)*k*g[i+][j][];
}
else if(k==a[i]){
g[i][j+k][]+=g[i+][j][],f[i][j+k][]+=f[i+][j][]+(i-p)*k*g[i+][j][];
g[i][j+k][]+=g[i+][j][],f[i][j+k][]+=f[i+][j][]+(i-p)*k*g[i+][j][];
}
else{
g[i][j+k][]+=g[i+][j][],f[i][j+k][]+=f[i+][j][]+(i-p)*k*g[i+][j][];
}
}
else{//after
if(j-k<) continue; if(k<a[i]){
f[i][j-k][]+=f[i+][j][]+g[i+][j][]*(p-i)*k,g[i][j-k][]+=g[i+][j][];
f[i][j-k][]+=f[i+][j][]+g[i+][j][]*(p-i)*k,g[i][j-k][]+=g[i+][j][];
}
else if(k==a[i]){
f[i][j-k][]+=f[i+][j][]+g[i+][j][]*(p-i)*k,g[i][j-k][]+=g[i+][j][];
f[i][j-k][]+=f[i+][j][]+g[i+][j][]*(p-i)*k,g[i][j-k][]+=g[i+][j][];
}
else{
f[i][j-k][]+=f[i+][j][]+g[i+][j][]*(p-i)*k,g[i][j-k][]+=g[i+][j][];
}
}
}
}
}
for(int j=;j<=up;j++){
if((fix-x<=j)&&(j<x+fix)){
ret+=f[][j][]+f[][j][];
}
}
}
}
return ret;
}
int main(){
scanf("%lld%lld",&L,&R);
scanf("%d",&m);
L--;
cnt=;
while(L){
a[++cnt]=L%m;
L/=m;
}
if(cnt==){
ansl=;
}
else{
ansl=wrk();
} cnt=;
while(R){
a[++cnt]=R%m;
R/=m;
}
ansr=wrk();
printf("%lld",ansr-ansl);
}
法二:大众法。
直接钦定1号位置是最优位置,计算出来所有的总和ans
调整。
枚举位置p从2~cnt,表示要计算从p-1移动到p,会有多少个数的代价减少多少。
代价就是,sum(1,p-1)-sum(p,cnt)
设f[i][a-b][0/1]表示,第i位,这个sum的差值,有没有限制情况下,多少个数符合这个情况。
循环完一个p之后,
把a-b<0的f,ans-=(a-b)*f[i][a-b][0/1]
a-b>=0的不管。
这样进行cnt次,一定可以把所有的数移动到最优解的位置。
网上题解很多,代码就不贴了。(我也没写)
[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水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- 【数位DP】SCOI2014 方伯伯的商场之旅
题目内容 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子. 说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 ...
- bzoj3598 [Scoi2014]方伯伯的商场之旅
数位dp,我们肯定枚举集合的位置,但是如果每次都重新dp的话会很麻烦,所以我们可以先钦定在最低位集合,dp出代价,然后再一步步找到正确的集合点,每次更改的代价也dp算就好了. #include < ...
- 2019.03.28 bzoj3598: [Scoi2014]方伯伯的商场之旅(带权中位数+数位dp)
传送门 题意咕咕咕自己读吧挺简单的 思路: 由带权中位数的性质可以得到对于每个数放在每个二进制位的代价一定是个单调或者单峰函数,因此我们先把所有的数都挪到第一个位置,然后依次向右枚举峰点(极值点)把能 ...
- BZOJ.3598.[SCOI2014]方伯伯的商场之旅(贪心 数位DP)
题目链接 先考虑,对于确定的一个数,怎样移动代价最少(或者移到哪个位置最优)? 假设我们都移到下标\(1\)位置(设集合点为\(1\)),那么移动到下标\(2\)与\(1\)相比代价差为:\(下标&l ...
- 【bzoj3598】 Scoi2014—方伯伯的商场之旅
http://www.lydsy.com/JudgeOnline/problem.php?id=3598 (题目链接) 题意 Solution 原来这就是极水的数位dp,呵呵= =,感觉白学了.htt ...
- BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)
看到数据范围就可以猜到数位dp了.显然对于一个数最后移到的位置应该是其中位数.于是考虑枚举移到的位置,那么设其左边和为l,左右边和为r,该位置数为p,则需要满足l+p>=r且r+p>=l. ...
随机推荐
- 20155211 网络攻防技术 Exp08 Web基础
20155211 网络攻防技术 Exp08 Web基础 实践内容 Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. We ...
- web窗体的运用
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebAp ...
- FAT32文件系统学习(2) —— FAT表
1.题外话 在继续本文学习FAT32文件系统之前,先来插入一点别的话题.我们都知道U盘有一个属性是容量,就拿笔者的U盘为例,笔者手上的U盘是金士顿的DataTraveler G3 4GB的一个U盘.电 ...
- [胡泽聪 趣题选讲]大包子环绕宝藏-[状压dp]
Description 你有一个长方形的地图,每一个格子要么是一个障碍物,要么是一个有一定价值的宝藏,要么是一个炸弹,或者是一块空地.你的初始位置已经给出.你每次可以走到上.下.左.右这四个相邻的格子 ...
- cocos2d-x学习记录5——CCTransition场景过渡
利用CCTransition能够创建出一系列的场景过渡动画,能够使场景切换时更加绚丽丰富. CCTransition派生出很多过渡动画,传入的参数一般包括过渡时间和创建的场景. MyScene.h内容 ...
- Centos7下python3安装pip-9.0.1
pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法 1.下载pip安装包 [root@localhost ~]# wget https://pypi ...
- [CF1007B]Pave the Parallelepiped[组合计数+状态压缩]
题意 \(t\) 组询问,给你 \(A, B, C\) ,问有多少组三元组 \((a, b, c)\) 满足他们任意排列后有: \(a|A,\ b|B,\ c|C\) . \(A,B,C,t\leq ...
- NodeJS旅程 : express - nodejs MVC 中的王牌
express 正如ASP.NET MVC 在作为.net平台下最佳的 Mvc框架的地位一样,express在 node.js 环境也有着相同的重要性.在百度上 "nodejs expres ...
- 在 Azure 上部署 Asp.NET Core Web App
在云计算大行其道的时代,当你要部署一个网站时第一选择肯定是各式各样的云端服务.那么究竟使用什么样的云端服务才能够以最快捷的方式部署一个 ASP.NET Core的网站呢?Azure 的 Web App ...
- pandas 初识(一)
基本内容 Series: Series 是有一组数据(numpy的数据类型 numpy.ndarray)以及一组数据标签(即索引)组成,可以看成一个一个定长的有序字典(索引值到数据值的一个映射) ob ...