zoukankan      html  css  js  c++  java
  • SCOI2014 方伯伯的商场之旅

    方伯伯的商场之旅

    方伯伯有一天去参加一个商场举办的游戏。商场派了一些工作人员排成一行。每个人面前有几堆石子。说来也巧,位置在 (i) 的人面前的第 (j) 堆的石子的数量,刚好是 (i) 写成 (K) 进制后的第 (j) 位。

    现在方伯伯要玩一个游戏,商场会给方伯伯两个整数 (L,R)。方伯伯要把位置在 ([L, R]) 中的每个人的石子都合并成一堆石子。每次操作,他可以选择一个人面前的两堆石子,将其中的一堆中的某些石子移动到另一堆,代价是移动的石子数量( imes)移动的距离。商场承诺,方伯伯只要完成任务,就给他一些椰子,代价越小,给他的椰子越多。所以方伯伯很着急,想请你告诉他最少的代价是多少。

    例如:若要合并十进制下的位置在 (12312_{(10)}) 的人面前的石子,所需的最少代价为:
    (1 imes 2 + 2 imes 1 + 3 imes 0 + 1 imes 1 + 2 imes 2 = 9)
    即把所有的石子都合并在第三堆时代价最少。

    对于所有的数据,(1 leq L leq R leq 10^{15}, 2 leq K leq 20)

    题解

    这个最优点不能直接找出来。但是注意到这个最优点本质上是带权重心,所以可以沿用调整法。

    具体而言,我们一开始把集结点设为(1)求个和。然后枚举集结点从(i)挪动到(i+1),如果挪动能使答案减小就把变化量加到答案里面;如果不能就不计入答案。

    int64 L,R,dp[51][2],f[51][2],g[51][1000][2];
    int K,n,a[51];
    
    int64 dfs(int n,bool flag){ // move to 1
    	if(!n){
    		f[0][flag]=1;
    		return 0;
    	}
    	if(dp[n][flag]!=-1) return dp[n][flag];
    	int64 val=0,cnt=0;
    	int up=flag?a[n]:K-1;
    	for(int i=0;i<=up;++i){
    		val+=dfs(n-1,flag and i==up)+f[n-1][flag and i==up]*i*(n-1);
    		cnt+=f[n-1][flag and i==up];
    	}
    	f[n][flag]=cnt;
    	return dp[n][flag]=val;
    }
    int64 calc(int n,int v,int pos,bool flag){ // move from pos-1 to pos
    	if(!n) return v;
    	if(g[n][v][flag]!=-1) return g[n][v][flag];
    	int64 ans=0;
    	int up=flag?a[n]:K-1,c=n>=pos?1:-1;
    	for(int i=0;i<=up;++i){
    		if(v+c*i<0) break;
    		ans+=calc(n-1,v+c*i,pos,flag and i==up);
    	}
    	return g[n][v][flag]=ans;
    }
    int64 solve(int64 x){
    	if(!x) return 0;
    	for(n=0;x;x/=K) a[++n]=x%K;
    	memset(dp,-1,sizeof dp);
    	int64 ans=dfs(n,1);
    	for(int i=2;i<=n;++i){
    		memset(g,-1,sizeof g);
    		ans-=calc(n,0,i,1);
    	}
    	return ans;
    }
    int main(){
    	read(L),read(R),read(K);
    	printf("%lld
    ",solve(R)-solve(L-1));
    	return 0;
    }
    
  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/autoint/p/13083299.html
Copyright © 2011-2022 走看看