题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅

思路

数位DP

dalao说这是数位dp水题,果然是我太菜了...

自己是不可能想出来的。这道题在讲课时作为例题,大概听懂了思路,简单复述一下。

首先根据数据范围和部分题意,不难看出是数位dp。

但是和常规的数位dp不同,我们并不知道每个数字最后的集结点。

于是我们不妨钦定所有石子最后都聚在最低位(第一位)。此时的总代价记作\(cost\),可以通过一次简单的数位dp得到。

但这样显然不是最优解,对于有的数,石子聚在更高位代价更少。于是我们就逐位移动。

比如说对于数字\(i\),石子现在都聚在第一位(最低位),要把石子移到第二位,那么\(i\)的第二位及更高位移动的代价减少,\(i\)的第一位移动代价增加,类似树形dp中的换根dp。

用\(delta(i)\)表示 数字i的石子 从 聚在第一位 移至 聚在第二位,花费的代价 的 减少量(这句话有点长)。

当\(delta(i)<0\)时,说明花费的代价没有减少,反而增加了,那么我们就不移动i的石子,否则把i的石子都移至第二位。基于上述操作,现在的总花费为\(cost-\sum_{i=l}^r \max(delta(i),0)\)。

式子中的\(\sum_{i=l}^r \max(delta(i),0)\)可以再用一次数位dp计算(类似换根dp的第二次dp)。

现在只是把能移的石子都从第一位移到第二位,之后再按上述方法,把能移的石子从第二位移到第三位、从第三位移到第四位...最后所有石子都被移到了最优的位置



可以结合代码理解。


Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l,r,k,a[80],dp[80][4000][2][2];
ll dfs(int pos,int sum,bool lead,bool limit){
if(pos==0) return sum;
ll &ans=dp[pos][sum][lead][limit];
if(ans!=-1) return ans;
ans=0;
for(int i=0,up=limit?a[pos]:k-1;i<=up;++i){
if(!i&&lead) ans+=dfs(pos-1,0,true,limit&&i==a[pos]);
else ans+=dfs(pos-1,sum+i*(pos-1),false,limit&&i==a[pos]);
}
return ans;
}
ll dfs(int to,int pos,int sum,bool lead,bool limit){
if(pos==0) return max(sum,0);
ll &ans=dp[pos][sum+500][lead][limit];
if(ans!=-1) return ans;
ans=0;
for(int i=0,up=limit?a[pos]:k-1;i<=up;++i){
if(!i&&lead) ans+=dfs(to,pos-1,0,true,limit&&i==a[pos]);
else if(pos>=to) ans+=dfs(to,pos-1,sum+i,false,limit&&i==a[pos]);
else ans+=dfs(to,pos-1,sum-i,false,limit&&i==a[pos]);
}
return ans;
}
ll solve(ll num){
memset(dp,-1,sizeof(dp));
int len=0;
while(num) a[++len]=num%k,num/=k;
ll res=dfs(len,0,true,true);
for(int i=2;i<=len;++i){
memset(dp,-1,sizeof(dp));
res-=dfs(i,len,0,true,true);
}
return res;
}
int main(){
scanf("%lld%lld%d",&l,&r,&k);
printf("%lld\n",solve(r)-solve(l-1));
return 0;
}

洛谷P3286 [SCOI2014]方伯伯的商场之旅的更多相关文章

  1. 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树

    洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...

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

    3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 449  Solved: 254[Submit][Sta ...

  3. 洛谷 P3285 [SCOI2014]方伯伯的OJ

    看到这题,第一眼:平衡树水题,随便做一做好了 然后....我在花了n个小时去调试(维护平衡树父节点)之后,... 调了三个小时后,第一次失败的代码(只能查找排名为k的用户编号,不能根据编号查排名) # ...

  4. 洛谷 P3285 - [SCOI2014]方伯伯的OJ(平衡树)

    洛谷题面传送门 在酒店写的,刚了一整晚终于调出来了-- 首先考虑当 \(n\) 比较小(\(10^5\) 级别)的时候怎么解决,我们考虑将所有用户按排名为关键字建立二叉排序树,我们同时再用一个 map ...

  5. 洛谷 P3287 - [SCOI2014]方伯伯的玉米田(BIT 优化 DP)

    洛谷题面传送门 怎么题解区全是 2log 的做法/jk,这里提供一种 1log 并且代码更短(bushi)的做法. 首先考虑对于一个序列 \(a\) 怎样计算将其变成单调不降的最小代价.对于这类涉及区 ...

  6. 【bzoj3598】: [Scoi2014]方伯伯的商场之旅

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

  7. [SCOI2014]方伯伯的商场之旅

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

  8. 【数位DP】SCOI2014 方伯伯的商场之旅

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

  9. 洛谷P3287 [SCOI2014]方伯伯的玉米田(树状数组)

    传送门 首先要发现,每一次选择拔高的区间都必须包含最右边的端点 为什么呢?因为如果拔高了一段区间,那么这段区间对于它的左边是更优的,对它的右边会更劣,所以我们每一次选的区间都得包含最右边的端点 我们枚 ...

随机推荐

  1. leetcode 699. Falling Squares 线段树的实现

    线段树实现.很多细节值得品味 都在注释里面了 class SegTree: def __init__(self,N,query_fn,update_fn): self.tree=[0]*(2*N+2) ...

  2. 2018-2-13-win10-uwp-设置启动窗口大小--获取窗口大小

    title author date CreateTime categories win10 uwp 设置启动窗口大小 获取窗口大小 lindexi 2018-2-13 17:23:3 +0800 20 ...

  3. springcloud:RPC和HTTP

    1.RPC和HTTP 无论是微服务还是SOA,都面临着服务间的远程调用.那么服务间的远程调用方式有哪些呢? 常见的远程调用方式有以下2种: RPC:Remote Produce Call远程过程调用, ...

  4. mybatis学习:mybatis注解开发一对一的查询配置

    实体类: public class Account { private Integer id; private Integer uid; private Double money; private U ...

  5. (大概是最全的解决方法)使用bandicam录制视频导入pr后音画不同步问题

    遇到这个问题大部分都是使用了VBR来录制视频导致的, 搜集了各种能够找到的方法,并没有每个尝试过 一 Handbrake转码 Audio out of sync AFTER importing 解决方 ...

  6. CSS3实现3D地球自转行星公转

    截图效果:实际效果是动态的:地球自西向东自转,行星绕着地球公转,轨道也会转动 HTML页面代码: <!DOCTYPE html> <html lang="en"& ...

  7. web前端学习(四)JavaScript学习笔记部分(7)-- JavaScript DOM对象控制HTML元素详解

    1.方法 getElementsByName() 获取name 可以获取一个数组类型数据(参数加引号) getElementsByTagName() 获取元素   getAttribute() 获取元 ...

  8. 容斥原理学习(Hdu 4135,Hdu 1796)

    题目链接Hdu4135 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. C# 多线程的代价~内存都被吃了!

    异步操作是.net4.5推出的新名词,事实上,这东西早就有了,它归根结底是通过线程池来实现的,即将一个大任务分成多个小任何块,每个线程并行处理其中的一个,完成后再把结果告诉主线程,在.net4.5推出 ...

  10. Web前端开发工程师需要掌握哪些核心技能?

    Web前端开发所涉及的内容主要包括W3C标准中的结构.行为和表现,那么这三项中我们需要掌握的核心技能是什么呢? 1.开发语言 HTML发展历史有二十多年,历经多次版本更新,HTML5和CSS3的出现又 ...