【做题】方伯伯的商场之旅——枚举决策

这道题的数位dp是很显然的。然而,本题不仅要计数还要保证最优化,这使得我们难以得到一个简单的dp状态表示方式。

遗憾的是考虑dp状态数的直接减少是一个错误的思考方向。本人在此浪费了几个小时的时间。

注意到虽然是最优化,但决策数是非常少的,仅有O(logn)级别。同时,我们可以很容易地判断一个解是不是最优的。

于是,我们可以枚举最终合并到哪一位,然后就很容易了,本人是维护满足这个条件的数的个数和答案的和,这里就不详细讲了。

最后一个问题在于一个数可能在多个位置都是决策最优的。注意到它的充要条件是选择的那一位(设值为x)左右两边sum的差为0或x,于是只要在判断时把闭区间改成半闭半开区间就可以了。

这数位和为sum,则时间复杂度为O(log2n*sum*k)。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll,ll> pll;
 5 const int N = 55, SUM = 250, K = 25;
 6 ll dp[N][SUM][K],l,r,su[N][SUM][K];
 7 int num[N],cur,k,cnt;
 8 pll dfs(int pos,int sum,int val,bool lim) {
 9   if (pos == 0) return pll(sum <= 2 * val,0);
10   if ((!lim) && (~dp[pos][sum][val]))
11     return pll(dp[pos][sum][val],su[pos][sum][val]);
12   ll ta = 0, tb = 0;
13   pll tmp;
14   for (int i = 0 ; i <= (lim ? num[pos] : k-1) ; ++ i) {
15     if (pos < cur && sum - i <= 0) break;
16     tmp = dfs(pos-1,pos < cur ? sum-i : sum+i,pos == cur ? i : val,lim && (i == num[pos]));
17     ta += tmp.first;
18     tb += tmp.second + tmp.first * abs(pos-cur) * i;
19   }
20   if (!lim) {
21     dp[pos][sum][val] = ta;
22     su[pos][sum][val] = tb;
23   }
24   return pll(ta,tb);
25 }
26 ll solve(ll x) {
27   ll res = 0;
28   cnt = 0;
29   while (x) num[++cnt] = x%k, x /= k;
30   for (cur = 1 ; cur <= cnt ; ++ cur) {
31     memset(dp,-1,sizeof dp);
32     memset(su,-1,sizeof su);
33     res += dfs(cnt,0,0,1).second;
34   }
35   return res;
36 }
37 int main() {
38   scanf("%lld%lld%d",&l,&r,&k);
39   printf("%lld\n",solve(r) - solve(l-1));
40   return 0;
41 }

小结:对于难维护的东西,可以通过添加额外信息来完成。

原文地址:https://www.cnblogs.com/cly-none/p/8530229.html

时间: 2024-11-16 14:32:28

【做题】方伯伯的商场之旅——枚举决策的相关文章

「SCOI2014」方伯伯的商场之旅

「SCOI2014」方伯伯的商场之旅 题目描述 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石子的数量,刚好是 \(i\) 写成 \(K\) 进制后的第 \(j\) 位. 现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 \(L,R\).方伯伯要把位置在 \([L, R]\) 中的每个人的石子都合并成一堆石子.每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价

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

方伯伯的商场之旅 输入格式: 输入仅有1 行,包含3 个用空格分隔的整数L,R,K,表示商场给方伯伯的2 个整数,以及进制数 输出格式: 输出仅有1 行,包含1 个整数,表示最少的代价. 样例输入: 3 8 3 样例输出: 5 数据范围: 时间限制: 3s 空间限制: 64M 具体思路:数位DP 先假装所有数都转移到第一位上, 然后扫一下其他位,把对答案有益的加上 AC代码 #include<bits/stdc++.h> using namespace std; #define int lon

[SCOI2014]方伯伯的商场之旅

Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的第 j 位. 现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 L,R.方伯伯要把位置在 [L, R] 中的每个人的石子都合并成一堆石子.每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量 * 移动的距离.商场承诺,方伯伯只要完成任务,就给他一些椰子,

【SCOI2014】【BZOJ3598】方伯伯的商场之旅(数位dp)

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3598 题意: 对于一个数x,它含有一些小石子,每个石子的值为a[i](a[i]为x在k进制下的第i位),选一个石子的位置pos使得sum(a[i] * abs(i-pos))最小. 求出[L,R]中所有数这个值的和. 题解: 对于一个数,我们枚举最优位置时,可以发现从i->i+1的变化为+pre[i]-suf[i+1](分别为前缀和与后缀和). 30%的暴力分,我们枚举[L,R]中的数,然

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

http://www.lydsy.com/JudgeOnline/problem.php?id=3598 (题目链接) 题意 Solution 原来这就是极水的数位dp,呵呵= =,感觉白学了.http://www.cnblogs.com/Artanis/p/3751644.html 首先我们考虑集结点设置第一位(最低位)上,数位dp计算出此时的代价. 如果将集结点往高位移动一位,那么此时代价会怎么变化呢,位置比集结点高的数位上的数它们的距离全部-1,位置比集结点低的数位上的数它们的距离全部+1

bzoj 3598 [ Scoi 2014 ] 方伯伯的商场之旅 ——数位DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 数位DP...东看西看:http://www.cnblogs.com/Artanis/p/3751644.html     https://www.cnblogs.com/MashiroSky/p/6399095.html 好巧妙的思路啊!这样统计的东西就变得很简单了: 好美的 dfs!数位DP用 dfs 好像能变得很清楚. 代码如下: #include<iostream> #in

bzoj 3598: [Scoi2014]方伯伯的商场之旅【数位dp】

参考了这个http://www.cnblogs.com/Artanis/p/3751644.html,好像比一般方法好写 大概思想就是先计算出把所有石子都合并到1位置的代价,这样显然有一些是不优的,然后再分别计算把合并到1的石子合并到p,能优化多少 这个计算就是枚举2到tot位,对于每一位计算挪到这位能被优化的数最多能被优化多少,因为合并点右移的代价是sum[w]-(sum[n]-sum[w]),所以只要这个为负数就退出即可 #include<iostream> #include<cst

BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

3595: [Scoi2014]方伯伯的OjTime Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status] Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-",一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号: 1.操作格式为1 x y,意味着将编号为z的用户编号改为V,而排名不变,执行完该操作后需要

[SCOI2014]方伯伯的玉米田 //二维树状数组优化DP//unfinished

闲的慌,从HZOJ里挑了道DP题来做,没想到这么恐怖 但是已经开了坑也不能退,干脆写吧 题目: 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美.这排玉米一共有N株,它们的高度参差不齐.方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列.方伯伯可以选择一个区间,把这个区间的玉米全部拔高1单位高度,他可以进行最多K次这样的操作.拔玉米则可以随意选择一个集合的玉米拔掉.问能最多剩多少株玉米,来构成一排美丽的玉米