[BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)

时间:2023-01-08 20:25:05

3598: [Scoi2014]方伯伯的商场之旅

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 449  Solved: 254
[Submit][Status][Discuss]

Description

方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的第 j 位。
现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 L,R。方伯伯要把位置在 [L, R]
中的每个人的石子都合并成一堆石子。每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量 *
移动的距离。商场承诺,方伯伯只要完成任务,就给他一些椰子,代价越小,给他的椰子越多。所以方伯伯很着急,想请你告诉他最少的代价是多少。
例如:10 进制下的位置在 12312 的人,合并石子的最少代价为:
1 * 2 + 2 * 1 + 3 * 0 + 1 * 1 + 2 * 2 = 9
即把所有的石子都合并在第三堆

Input

输入仅有 1 行,包含 3 个用空格分隔的整数 L,R,K,表示商场给方伯伯的 2 个整数,以及进制数

Output

输出仅有 1 行,包含 1 个整数,表示最少的代价。

Sample Input

3 8 3

Sample Output

5

HINT

1 < =  L < =  R < =  10^15, 2 < =  K < =  20

Source

一眼数位DP,但是具体实现感觉非常难以理解。

主要思路是:先默认每个人都将式子移到最低的那一位上去,然后从2开始枚举如果将其中一些人的石子从i-1移到i最终结果会优多少。

第一个DP就是普通的数位DP,但是第二个DP就有一个很难处理的问题:如何确定到底那些人的石子可以(或需要)从i-1移到i,因为每个人最终所选的那一位都不同。

这里有一种新型的记忆化搜索,dfs(i,sum,lim)表示(从高到低)前i位将(那些可以或需要移动的)人移动,且前i位已经变优了sum,所能得到的最终解(也就是最后最多能变优多少)。一般记搜都是形如dfs(i)+=dfs(i+1)+f(i)的(最终返回的sum),但这种记搜是dfs(i,sum,lim)+=dfs(i+1,sum+f[i],lim')(最终返回的仍然是sum,只是在递归底层被处理过的sum)。也就是说,普通记搜记录的是这个状态到目标状态(递归底层)的信息,而这种记录的是初始状态到这个状态的信息。

这种记搜实际上不应该从DP的角度去理解,而是应该从搜索的角度,实际上就是一个记录了中间状态(sum)的搜索,在底层进行处理。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
#define ll long long
using namespace std; int k,num[];
ll l,r,len,f[][**][]; ll dfs1(int pos,int sum,bool lim){
if (pos>len) return sum;
if (f[pos][sum][lim]!=-) return f[pos][sum][lim];
ll res=; int end=(lim?num[pos]:k-);
rep(i,,end) res+=dfs1(pos+,sum+i*(pos-),lim && (i==end));
return f[pos][sum][lim]=res;
} ll dfs2(int pos,int sum,int m,bool lim){
if (pos>len) return max(sum,);
if (f[pos][sum][lim]!=-) return f[pos][sum][lim];
ll res=; int end=(lim?num[pos]:k-);
rep(i,,end) res+=dfs2(pos+,sum+((pos<m)?-i:i),m,lim && (i==end));
return f[pos][sum][lim]=res;
} ll solve(ll n){
len=; while (n) num[++len]=n%k,n/=k;
reverse(num+,num+len+);
memset(f,-,sizeof(f));
ll res=dfs1(,,);
rep(i,,len) memset(f,-,sizeof(f)),res-=dfs2(,,i,);
return res;
} int main(){
freopen("bzoj3598.in","r",stdin);
freopen("bzoj3598.out","w",stdout);
scanf("%lld%lld%d",&l,&r,&k);
printf("%lld\n",solve(r)-solve(l-));
return ;
}

[BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)的更多相关文章

  1. bzoj 3598 &lbrack;Scoi2014&rsqb;方伯伯的商场之旅——数位dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 TJ:https://www.cnblogs.com/Zinn/p/9351218.h ...

  2. BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)

    看到数据范围就可以猜到数位dp了.显然对于一个数最后移到的位置应该是其中位数.于是考虑枚举移到的位置,那么设其左边和为l,左右边和为r,该位置数为p,则需要满足l+p>=r且r+p>=l. ...

  3. bzoj3598 &lbrack;Scoi2014&rsqb;方伯伯的商场之旅

    数位dp,我们肯定枚举集合的位置,但是如果每次都重新dp的话会很麻烦,所以我们可以先钦定在最低位集合,dp出代价,然后再一步步找到正确的集合点,每次更改的代价也dp算就好了. #include &lt ...

  4. 2019&period;03&period;28 bzoj3598&colon; &lbrack;Scoi2014&rsqb;方伯伯的商场之旅(带权中位数&plus;数位dp)

    传送门 题意咕咕咕自己读吧挺简单的 思路: 由带权中位数的性质可以得到对于每个数放在每个二进制位的代价一定是个单调或者单峰函数,因此我们先把所有的数都挪到第一个位置,然后依次向右枚举峰点(极值点)把能 ...

  5. bzoj 3598 &lbrack; Scoi 2014 &rsqb; 方伯伯的商场之旅 ——数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 数位DP...东看西看:http://www.cnblogs.com/Artanis/ ...

  6. 洛谷P3286 &lbrack;SCOI2014&rsqb;方伯伯的商场之旅

    题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅 思路 数位DP dalao说这是数位dp水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...

  7. 【bzoj3598】&colon; &lbrack;Scoi2014&rsqb;方伯伯的商场之旅

    Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...

  8. 【bzoj3598】 Scoi2014—方伯伯的商场之旅

    http://www.lydsy.com/JudgeOnline/problem.php?id=3598 (题目链接) 题意 Solution 原来这就是极水的数位dp,呵呵= =,感觉白学了.htt ...

  9. &lbrack;SCOI2014&rsqb;方伯伯的商场之旅

    Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...

随机推荐

  1. Tomcat https自制证书和浏览器配置

    Tomcat配置成https后,如过使用的是自己的证书,登陆首页时,总是提示证书安全问题,网上的很多资料有描述,但比较复杂,找了几个配置不成功,现在描述一个比较简单的方法. 生成证书的脚本 #!/bi ...

  2. YII获取刚插入数据的id主键

    单条数据时model->attributes['id']; 循环插入时使用 Yii::app()->db->getLastInsertID() 获取 循环插入时需要每次插入后重置 m ...

  3. Oracle EBS-SQL &lpar;MRP-5&rpar;&colon;重起MRP Manager&period;sql

    UPDATE fnd_concurrent_processes SET process_status_code = 'K' WHERE process_status_code not in ('K', ...

  4. iOS开发笔记 基于wsdl2objc调用asp&period;net WebService

    1.准备 先下载待会要用到的工具 WSDL2ObjC-0.6.zip WSDL2ObjC-0.7-pre1.zip 我用的是WSDL2ObjC-0.6.zip 1.1搭建asp.net WebServ ...

  5. git 使用详情

    一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在*服务器的,而干活的时候,用的都是自己的电脑,所以 ...

  6. 构建高性能web站点-阅读笔记(一)

    看完前9章,也算是看完一半了吧,总结一下. 郭欣这个名字或许并不响亮,但是这本书写的确实真好!百度一下他的名字也能够看到他是某些公司的创始人和投资者,当然他本人必定是大牛无疑. 从网页的动静分离到网络 ...

  7. (转)ZXing解析二维码

    1 ZXing解析二维码 上一篇文件已经说过如何用ZXing进行生成二维码和带图片的二维码,下面说下如何解析二维码 二维码的解析和生成类似,也可以参考google的一个操作类 BufferedImag ...

  8. Apache和nginx 域名配置

    apache配置 一.hosts配置: 1.用编辑器打开hosts文件,位置:C:\Windows\System32\drivers\etc目录下 2.在hosts文件里添加自己的域名配置,配置规则如 ...

  9. Jvm中时区设置方式

    Jvm中时区设置方式2018年08月08日 08:19:31 liumiaocn 阅读数:156更多个人分类: 编程语言版权声明:本文为博主原创文章,未经博主允许欢迎转载,但请注明出处. https: ...

  10. POJ 3220 位运算&plus;搜索

    转载自:http://blog.csdn.net/lyhypacm/article/details/5813634 DES:相邻的两盏灯状态可以互换,给出初始状态.询问是否能在三步之内到达.如果能的话 ...