列表

详情


NC20298. [SCOI2014]方伯伯的商场之旅

描述

方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的第 j 位。 
现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 L,R。方伯伯要把位置在 [L, R] 中的每个人的石子都合并成一堆石子。每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量 * 移动的距离。
商场承诺,方伯伯只要完成任务,就给他一些椰子,代价越小,给他的椰子越多。所以方伯伯很着急,想请你告诉他最少的代价是多少。 
例如:10 进制下的位置在 12312 的人,合并石子的最少代价为: 1 * 2 + 2 * 1 + 3 * 0 + 1 * 1 + 2 * 2 = 9 即把所有的石子都合并在第三堆

输入描述

输入仅有 1 行,包含 3 个用空格分隔的整数 L,R,K,表示商场给方伯伯的 2 个整数,以及进制数

输出描述

输出仅有 1 行,包含 1 个整数,表示最少的代价。

示例1

输入:

3 8 3

输出:

5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 25ms, 内存消耗: 8236K, 提交时间: 2022-07-15 11:53:59

#include <bits/stdc++.h>
#define int long long
using namespace std;
int L,R,K;
int a[100],f[100][10000];

int dfs(int now,int sum,int p,int lim){
    if(!now)return max(sum,0LL);
    if(!lim&&~f[now][sum])return f[now][sum];
    int ans=0;
    int num=lim?a[now]:K-1;
    for(int i=0;i<=num;i++)
        ans+=dfs(now-1,sum+(p==1?i*(now-1):(now<p?-i:i)),p,lim&&(i==num));
    if(!lim)f[now][sum]=ans;
    return ans;
}

inline int Solve(int x){
    int n=0;
    while(x){
        a[++n]=x%K;
        x/=K;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        memset(f,-1,sizeof(f));
        ans+=((i==1)?1:-1)*dfs(n,0,i,1);
    }
    return ans;
}

signed main(){
    scanf("%lld%lld%lld",&L,&R,&K);
    printf("%lld",Solve(R)-Solve(L-1));
    return 0;
}

上一题