BZOJ.3598.[SCOI2014]方伯伯的商场之旅(贪心 数位DP)
先考虑,对于确定的一个数,怎样移动代价最少(或者移到哪个位置最优)?
假设我们都移到下标\(1\)位置(设集合点为\(1\)),那么移动到下标\(2\)与\(1\)相比代价差为:\(下标<1的石子数和-下标>1的石子数和\)。
如果它为负,那么把移到\(1\)的代价加上它,令集合点变为\(2\)...
这样一直改变集合点,直到 \(下标<p的石子数和 \geq 下标>p的石子数和\)。那么移到\(p\)就是最优的。
这样感觉很对。怎么证明?
我们发现式子左边其实就是前缀和,右边是后缀和。因为石子数非负,所以随着\(p\)移动,前缀和是递增的,后缀和递减。
即如果出现 \(前缀和 \geq 后缀和\) 的情况,前缀和就永远大于等于后缀和了。
那么我们对\([l,r]\)的所有数都进行这个贪心。
首先我们要算出所有数集合到1的代价和。这个可以用数位DP算出(递推数的个数,用个数求和)。
然后枚举\(p=2\sim n\)位,我们可以求 以\(p\)为分界,前缀数位和 小于 后缀数位和 且 在\([0,r]\) 的数的个数。其中每个数会减少的代价就是\(前缀和-后缀和\)。
因为数位和最多差不多是230,可以直接枚举这两个状态。同样数位DP。
\(f[i][j][k][0/1]\)表示当前到第\(i\)位,总数位和为\(j\),\(p\)位之前的数位和为\(k\),是否到上界,的数的个数。
另外还可以直接减掉\(k\)那一维。。
记忆化就好写的多了(还快)。
//49592kb 404ms
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const int N=52,M=245;
int A[N];
LL g[N][2],sum[N][2],f[N][M][M][2];
LL Calc(LL x,int base)
{
int n=0;
for(; x; x/=base) A[++n]=x%base;
std::reverse(A+1,A+1+n);//
memset(g,0,sizeof g), memset(sum,0,sizeof sum);
g[0][1]=1;
for(int i=0; i<n; ++i)//好像还是从0方便。。
{
LL v=g[i][1]; int ai=A[i+1];
g[i+1][1]+=v, sum[i+1][1]=sum[i][1]+v*i*ai;
for(int j=0; j<ai; ++j) g[i+1][0]+=v, sum[i+1][0]+=sum[i][1]+v*i*j;
v=g[i][0];
for(int j=0; j<base; ++j) g[i+1][0]+=v, sum[i+1][0]+=sum[i][0]+v*i*j;
}
LL ans=sum[n][0]+sum[n][1];
for(int p=1; p<n; ++p)
{
f[0][0][0][1]=1;
for(int i=0; i<n; ++i)
{
int ai=A[i+1];
if(i+1<=p)
{
LL v;
for(int j=0,lim=i*(base-1); j<=lim; ++j)
{
if(v=f[i][j][j][1])//好不直观。。
{
f[i+1][j+ai][j+ai][1]+=v;//+=
for(int k=0; k<ai; ++k) f[i+1][j+k][j+k][0]+=v;
}
if(v=f[i][j][j][0])
for(int k=0; k<base; ++k) f[i+1][j+k][j+k][0]+=v;
}
}
else
{
LL v;
for(int j=0,lim=i*(base-1); j<=lim; ++j)
for(int k=0,lim2=p*(base-1); k<=lim2; ++k)
{
if(v=f[i][j][k][1])
{
f[i+1][j+ai][k][1]+=v;
for(int l=0; l<ai; ++l) f[i+1][j+l][k][0]+=v;
}
if(v=f[i][j][k][0])
for(int l=0; l<base; ++l) f[i+1][j+l][k][0]+=v;
}
}
}
for(int i=0,lim=p*(base-1); i<=lim; ++i)//pre
for(int j=i+1,lim2=n*(base-1); i+j<=lim2; ++j)//suf
ans+=(i-j)*(f[n][i+j][i][0]+f[n][i+j][i][1]);
for(int i=1; i<=n; ++i)
for(int j=0,lim=i*(base-1); j<=lim; ++j)
for(int k=0,lim2=p*(base-1); k<=lim2; ++k)
f[i][j][k][0]=0, f[i][j][k][1]=0;
}
return ans;
}
int main()
{
LL L,R; int K; scanf("%lld%lld%d",&L,&R,&K);
printf("%lld\n",Calc(R,K)-Calc(L-1,K));
return 0;
}
BZOJ.3598.[SCOI2014]方伯伯的商场之旅(贪心 数位DP)的更多相关文章
- bzoj 3598: [Scoi2014]方伯伯的商场之旅【数位dp】
参考了这个http://www.cnblogs.com/Artanis/p/3751644.html,好像比一般方法好写 大概思想就是先计算出把所有石子都合并到1位置的代价,这样显然有一些是不优的,然 ...
- bzoj 3598 [Scoi2014]方伯伯的商场之旅——数位dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 TJ:https://www.cnblogs.com/Zinn/p/9351218.h ...
- BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)
看到数据范围就可以猜到数位dp了.显然对于一个数最后移到的位置应该是其中位数.于是考虑枚举移到的位置,那么设其左边和为l,左右边和为r,该位置数为p,则需要满足l+p>=r且r+p>=l. ...
- 洛谷P3286 [SCOI2014]方伯伯的商场之旅
题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅 思路 数位DP dalao说这是数位dp水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 449 Solved: 254[Submit][Sta ...
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- [SCOI2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
- 【数位DP】SCOI2014 方伯伯的商场之旅
题目内容 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子. 说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 ...
- 【bzoj3598】 Scoi2014—方伯伯的商场之旅
http://www.lydsy.com/JudgeOnline/problem.php?id=3598 (题目链接) 题意 Solution 原来这就是极水的数位dp,呵呵= =,感觉白学了.htt ...
随机推荐
- AT91RM9200---电源管理控制器(PMC)介绍
1.前言 PMC通过集成的两个OSC(一个主振荡器和一个慢时钟振荡器32.768khz)和两个PLLs产生系统所有的clock. PMC提供时钟给嵌入式处理器,并通过在IDLE模式下停止处理器时钟,直 ...
- 红黑树与AVL树
概述:本文从排序二叉树作为引子,讲解了红黑树,最后把红黑树和AVL树做了一个比较全面的对比. 1 排序二叉树 排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索. 排序二叉树 ...
- Qt5 json 数据处理
QT4中使用第三方库QJson解析JSON文件. QT5新增加了处理JSON的类,类均以QJson开头,包含在QtCore模块中. 用到的头文件 #include <QJsonArray> ...
- Tpcc-MySQL对mysql数据库进行性能测试报告、分析及使用gnuplot生成图表展示
TPC-C是专门针对联机交易处理系统(OLTP系统)的规范,一般情况下我们也把这类系统称为业务处理系统. tpcc-mysql是percona基于TPC-C(下面简写成TPCC)衍生出来的产品,专用于 ...
- Makefile 隐含规则,模式规则,常见变量
隐含规则复杂的Makefile一般会使用隐含规则内的变量来简化编译处理.将隐含规则中使用的变量分成两种:一种是命令相关的,如“CC”:一种是参数相关的,如“CFLAGS”.这些变量都是大写表示. 常 ...
- LeetCode(35):搜索插入位置
Easy! 题目描述: 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1 ...
- SPOJ-SERVICE 线性dp+维度压缩
还是线性dp,有点感觉了,另外这个问题也可以用滚动数组 /* 依然是先按照阶段i划分, dp[i][j][k]表示完成第i个请求时,两个员工分别在j位置和k位置的费用(还有一个员工一定在位置p) dp ...
- Oracle回收站的清理方法
http://blog.itpub.net/18841027/viewspace-1057765/
- jQuery源码中的“new jQuery.fn.init()”什么意思?
所有文章搬运自我的个人主页:sheilasun.me 引子 最近打算试试看看jQuery的源码,刚开个头就卡住了.无论如何都理解不了jQuery源码入口部分中的 return new jQuery.f ...
- Codeforces Round #467 (Div. 2) E -Lock Puzzle
Lock Puzzle 题目大意:给你两个字符串一个s,一个t,长度<=2000,要求你进行小于等于6100次的shift操作,将s变成t, shift(x)表示将字符串的最后x个字符翻转后放到 ...