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>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll l,r,f[65][6005],ans;
int n,a[65],K;
ll dfs1(int pos,int s,bool lim)
{
    if(pos==0)return s;
    if(!lim&&f[pos][s]!=-1)return f[pos][s];
    int end=K-1; ll ret=0;
    if(lim)end=a[pos];
    for(int i=0;i<=end;i++)
        ret+=dfs1(pos-1,s+i*(pos-1),lim&&(i==end));
    if(!lim)f[pos][s]=ret;//!lim!
    return ret;
}
ll dfs(int pos,int s,int m,bool lim)
{
    if(s<0)return 0;//!
    if(pos==0)return s;
    if(!lim&&f[pos][s]!=-1)return f[pos][s];
    int end=K-1; ll ret=0;
    if(lim)end=a[pos];
    for(int i=0;i<=end;i++)
    {
        if(pos>=m)ret+=dfs(pos-1,s+i,m,lim&&(i==end));
        else ret+=dfs(pos-1,s-i,m,lim&&(i==end));
    }
    if(!lim)f[pos][s]=ret;
    return ret;
}
ll calc(ll x)
{
    int n=0;
    while(x)a[++n]=x%K,x/=K;
    memset(f,-1,sizeof f);
    ll ret=dfs1(n,0,1);
    for(int i=2;i<=n;i++)
    {
        memset(f,-1,sizeof f);
        ret-=dfs(n,0,i,1);
    }
    return ret;
}
int main()
{
    scanf("%lld%lld%d",&l,&r,&K);
    printf("%lld\n",calc(r)-calc(l-1));
    return 0;
}

原文地址:https://www.cnblogs.com/Zinn/p/9351218.html

时间: 2024-10-08 00:32:35

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

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」方伯伯的商场之旅

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

[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: [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

[SCOI 2014] 方伯伯的玉米田

[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3594 [算法] 首先有一个结论 : 每次选择的区间右端点一定是n 根据这个结论 , 设fi,j表示前i株玉米拔高j次的最长不下降子序列长度 则fi,j = max{fp,q + 1} (q <= j , ap + q <= ai + j) 二维树状数组优化即可 时间复杂度 : O(NKlogK ^ 2) [代码] #include<bits/stdc++.h> usi

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

这道题的数位dp是很显然的.然而,本题不仅要计数还要保证最优化,这使得我们难以得到一个简单的dp状态表示方式. 遗憾的是考虑dp状态数的直接减少是一个错误的思考方向.本人在此浪费了几个小时的时间. 注意到虽然是最优化,但决策数是非常少的,仅有O(logn)级别.同时,我们可以很容易地判断一个解是不是最优的. 于是,我们可以枚举最终合并到哪一位,然后就很容易了,本人是维护满足这个条件的数的个数和答案的和,这里就不详细讲了. 最后一个问题在于一个数可能在多个位置都是决策最优的.注意到它的充要条件是选

【BZOJ 3594】 [Scoi2014]方伯伯的玉米田

3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MB Submit: 633 Solved: 256 [Submit][Status][Discuss] Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列. 方伯伯可以选