• PE328 Lowest-cost Search


    题目大意

    猜数,每次询问一个数x返回大于小于等于,代价是数的大小x

    设C(n)表示数在[1,n]的最优策略下的答案,求(sum_{i=1}^{200000}C(i))

    题解

    显然可以n^3dp:设f[i,j]表示当前数的范围在[i,j]的答案,然后oeis即可得到n^2做法

    考虑如何n^2,转移枚举k然后min(max(f[i,k-1]+k,f[k+1,j]+k))->f[i,j],这样是n^3

    枚举j,然后从j往前枚举i,把max拆开发现前一段是f[k+1,j],后一段是f[i,k+1],因为小区间一定比包含它的区间更优

    所以单调维护分界点k0,把前面的丢到单调队列,后面的直接算k0,因为如果继续增大则f和k都会增大,显然不优

    这样就可以n^2了,但是空间开不下

    把n^3dp的决策点打表出来可以发现决策点到右端点的距离大约在n/logn左右,所以每次断开后的右段长度不长,而答案是Σ[1,i],所以断开后只会产生[1,i]和[j-s+1~j,j]

    设s=n/logn,维护一个s^2的滚动数组,每次求出[i-s+1,i]的dp值,然后即可求[1,i]的值

    时间复杂度(O(n^2/log n)),空间复杂度(O(n^2/log^2n)),60s跑完

    然后就看到了thread里3s跑完1e7的神仙老鸽

    code

    #pragma GCC optimize(3)
    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    #define ll long long
    #define N 13000
    #define file
    using namespace std;
    
    ll g[N+1][N+1],ans,inf;
    ll f[200001],s1,s2,s;
    int n,i,j,k,l,S,ed,h,t;
    int d[200001];
    int I[200001];
    
    ll get(int x,int y)
    {
    	if (x>=y) return 0;
    	return g[I[y]][y-x];
    }
    
    int main()
    {
    	freopen("PE328.in","r",stdin);
    	#ifdef file
    	freopen("PE328.out","w",stdout);
    	#endif
    	
    	memset(g,1,sizeof(g)),inf=g[0][0];
    	scanf("%d",&n);S=min(n,N);
    	fo(i,1,n) I[i]=i%N+1;
    	fo(i,2,n)
    	{
    		f[i]=inf,memset(g[I[i]],1,sizeof(g[I[i]]));
    		g[I[i]][0]=0;
    		ed=max(i-S+1,1);k=i;h=1,t=0;
    		fd(j,i-1,ed)
    		{
    			while (k>j && get(j,k-2)>get(k,i)) --k;
    			while (h<=t && k<=d[h]) ++h;
    			while (h<=t && get(d[t]+1,i)+d[t]>=get(j+1,i)+j) --t;
    			d[++t]=j;
    			s1=get(d[h]+1,i)+d[h];
    			s2=get(j,k-1)+k;
    			g[I[i]][i-j]=min(s1,s2);
    		}
    		fo(j,ed,i) s=get(j+1,i),s=max(s,f[j-1])+j,f[i]=min(f[i],s);
    	}
    	
    	fo(i,1,n) ans+=f[i];
    	printf("%lld
    ",ans);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    [原]RHCS集群的服务切换测试札记
    [原]从Clustering Factor说起
    命令行下设置IP地址的方法
    [原]SQL Server 2005 链接服务器使用一例
    [原]Oracle删除大表并回收空间的过程
    [转]从沙子到芯片:且看处理器是怎样炼成的
    [原] 在域环境中打开SSMS非常慢
    [原]将特定格式的string转换为DateTime
    [原] 在域环境中打开SSMS非常慢 续
    [转]Linux 下判断Server 内存是否不足
  • 原文地址:https://www.cnblogs.com/gmh77/p/14088146.html
Copyright © 2020-2023  润新知