bzoj3598 [Scoi2014]方伯伯的商场之旅
2017-10-24 22:34
363 查看
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 3Sample Output
5HINT
1 < = L < = R < = 10^15, 2 < = K < = 20正解:数位$dp$。
数位$dp$基本套路,拆成$[1,l-1]$和$[1,r]$,还有从高位到低位统计贡献。
我们先把所有数都移到第一位的答案统计出来,那么我们只要考虑哪些数需要往高位移。
我们把一个数从第$i-1$位移到第$i$位时候,可以发现,前$i-1$位数字距离$+1$,后面的数字距离$-1$,实际上就是前缀加一次,后缀减一次。
我们考虑每次往后移一位的贡献差,如果这个贡献差大于$0$,那就不用移了,因为这个贡献差其实是一个单峰函数。
那么我们可以先把全放到第一位的贡献算出来,设$f[i][j]$表示前$i$位,$[i+1,n]$位贡献和为$j$的总贡献,可以用数位$dp$搞出来。
然后每次算出贡献差并累加到答案中,状态与上面是一样的,只是转移略有不同。
建议使用记忆化搜索实现,比较好写。
#include <bits/stdc++.h> #define il inline #define RG register #define ll long long using namespace std; ll f[55][3000],l,r; int st[55],n,k; il ll dfs(RG int pos,RG ll s,RG int lim){ if (!pos) return s; if (!lim && f[pos][s]!=-1) return f[pos][s]; RG int end=lim ? st[pos] : k-1; RG ll res=0; for (RG int i=0;i<=end;++i) res+=dfs(pos-1,s+i*(pos-1),lim && i==end); if (!lim) f[pos][s]=res; return res; } il ll dfs(RG int pos,RG ll s,RG int m,RG int lim){ if (s<0) return 0; if (!pos) return s; if (!lim && f[pos][s]!=-1) return f[pos][s]; RG int end=lim ? st[pos] : k-1; RG ll res=0; for (RG int i=0;i<=end;++i) if (pos>=m) res+=dfs(pos-1,s+i,m,lim && i==end); else res+=dfs(pos-1,s-i,m,lim && i==end); if (!lim) f[pos][s]=res; return res; } il ll solve(RG ll x){ RG ll ans; n=0; while (x) st[++n]=x%k,x/=k; memset(f,-1,sizeof(f)),ans=dfs(n,0,1); for (RG int i=2;i<=n;++i) memset(f,-1,sizeof(f)),ans-=dfs(n,0,i,1); return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("shop.in","r",stdin); freopen("shop.out","w",stdout); #endif cin>>l>>r>>k; cout<<solve(r)-solve(l-1); return 0; }
相关文章推荐
- bzoj3598 [Scoi2014]方伯伯的商场之旅
- bzoj 3598 [Scoi2014]方伯伯的商场之旅 数位dp
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
- 【数位dp】[Scoi2014] bzoj3598 方伯伯的商场之旅
- 【bzoj 3598】: [Scoi2014]方伯伯的商场之旅
- 【bzoj3598】 Scoi2014—方伯伯的商场之旅
- BZOJ3598 [Scoi2014]方伯伯的商场之旅
- 【BZOJ3598】【SCOI2014】方伯伯的商场之旅
- BZOJ3598[Scoi2014]方伯伯的商场之旅 数位DP
- bzoj 3598: [Scoi2014]方伯伯的商场之旅【数位dp】
- [BZOJ3598]-[Scoi2014]方伯伯的商场之旅-数位dp
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
- bzoj3598[SCOI2014]方伯伯的商场之旅
- bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]
- BZOJ 3594: [Scoi2014]方伯伯的玉米田
- bzoj 3597: [Scoi2014]方伯伯运椰子 spfa判负环+分数规划
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
- 省选专练SCOI2014方伯伯的商场之旅
- BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)
- 【BZOJ3594】【SCOI2014】 方伯伯的玉米田