当前位置:首页 >> 硬件技术 >> 【SCOI2014】方伯伯的商场之旅【数位dp】【单峰函数】,htc710d手机(方伯是什么意思?)

【SCOI2014】方伯伯的商场之旅【数位dp】【单峰函数】,htc710d手机(方伯是什么意思?)

cpugpu芯片开发光刻机 硬件技术 1
文件名:【SCOI2014】方伯伯的商场之旅【数位dp】【单峰函数】,htc710d手机 【SCOI2014】方伯伯的商场之旅【数位dp】【单峰函数】

题意:给定 l,r,kl,r,kl,r,k ,对于一个 kkk 进制数,将数码看成这个位置的石子个数,每将一个石子移动 111 的距离需要 111 的代价。求 [l,r][l,r][l,r] 中的所有数在 kkk 进制下将石子集中在一个位置的最小代价之和。

l≤r≤1015,k≤20l\leq r\leq 10^{15},k\leq 20lr1015,k20

对于序列 {a1,a2,…,an}\{a_1,a_2,\dots,a_n\}{a1,a2,,an},显然将集中位置从 k−1k-1k1 移动到 kkk 会减少 ∑i=knai−∑i=1k−1ai\sum_{i=k}^n a_i-\sum_{i=1}^{k-1}a_ii=knaii=1k1ai 的代价。

枚举最优的位置,卡下前后的和的上下界,就可以数位 dp 了。

然而这个东西十分精神污染,反正我写了一天没写出来。

考虑更优美的做法。发现这个代价是关于集中位置的单峰函数,也就是一次往后移动如果贡献为负,那之后的贡献都为负。

所以有这样一个思路:先统计出放在最高位的总贡献,然后考虑每个移动产生的贡献,如果为正就把它加上。

可以设 dp(p,i,s,lim)dp(p,i,s,lim)dp(p,i,s,lim) 表示从高到低考虑到第 iii 位,如果把未考虑的记为 000,高于 ppp (含)的数码和减去低于 ppp (不含)的数码和为 sss,是否卡上界的总贡献。 p=1p=1p=1 的时候因为要算总贡献,要特殊处理一下。

为什么数位 dp 记忆化搜索这么好写啊……

#include <iostream>#include <cstdio>#include <cstring>#include <cctype>using namespace std;typedef long long ll;int B;int a[55],cnt,p;ll f[55][20005];ll dfs(int i,int s,int lim){if (!i||s<0) return max(s,0);if (!lim&&~f[i][s]) return f[i][s];int mx=lim? a[i]:B-1;ll ans=0;for (int x=0;x<=mx;x++)ans+=dfs(i-1,s+(p==1? x*(i-1):(i<p? -x:x)),lim&&x==mx);if (!lim) f[i][s]=ans;return ans;}inline ll calc(ll n){cnt=0;while (n) a[++cnt]=n%B,n/=B;memset(f,-1,sizeof(f)),p=1;ll ans=dfs(cnt,0,1);for (p=2;p<=cnt;p++) memset(f,-1,sizeof(f)),ans-=dfs(cnt,0,1);return ans; }int main(){ll l,r;cin>>l>>r>>B;cout<<calc(r)-calc(l-1);return 0;}
协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接