zoukankan      html  css  js  c++  java
  • 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<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1005;
    long long l,r,k,f[N][2],sm[N][2],g[N][N],a[N],tot;
    long long dp(int w,int lm)
    {
    	if(w==0)
    	{
    		sm[w][lm]=1;
    		return 0;
    	}
    	if(f[w][lm])
    		return f[w][lm];
    	long long r=0,s=0;
    	for(int i=0;i<=(lm?a[w]:k-1);i++)
    	{
    		r+=dp(w-1,lm&&(i==a[w]))+i*(w-1)*sm[w-1][lm&&(i==a[w])];
    		s+=sm[w-1][lm&&(i==a[w])];
    	}
    	sm[w][lm]=s;
    	return f[w][lm]=r;
    }
    long long wk(long long x)
    {
    	memset(f,0,sizeof(f));
    	tot=0;
    	while(x)
    		a[++tot]=x%k,x/=k;
    	return dp(tot,1);
    }
    long long dfs(int w,int lm,int p,int s)
    {
    	if(w==0)
    		return s;
    	if(!lm&&g[w][s])
    		return g[w][s];
    	long long r=0;
    	for(int i=0;i<=(lm?a[w]:k-1);i++)
    	{
    		long long nw=(w>=p?1:-1)*i+s;
    		if(nw<0)
    			break;
    		r+=dfs(w-1,lm&&i==a[w],p,nw);
    	}
    	if(lm)
    		return r;
    	return g[w][s]=r;
    }
    long long clc(long long x)
    {
    	tot=0;
    	while(x)
    		a[++tot]=x%k,x/=k;
    	long long r=0;
    	for(int i=2;i<=tot;i++)
    	{
    		memset(g,0,sizeof(g));
    		r+=dfs(tot,1,i,0);
    	}
    	return r;
    }
    int main()
    {
    	scanf("%lld%lld%lld",&l,&r,&k);
    	printf("%lld
    ",wk(r)-wk(l-1)-(clc(r)-clc(l-1)));
    	return 0;
    }
    
  • 相关阅读:
    Java HashMap存储问题
    <转>堆和栈的区别
    Linux shell命令
    DNS(三)DNS SEC(域名系统安全扩展)
    DNS (二)协议
    绕过CDN查找网站真实IP方法
    stream流思想应用
    http接口实现附件对接
    AQS深入分析
    AQS快速入门
  • 原文地址:https://www.cnblogs.com/lokiii/p/9617139.html
Copyright © 2011-2022 走看看