zoukankan      html  css  js  c++  java
  • BZOJ 1564: [NOI2009]二叉查找树

    听说n<=70?

    我一直以为n<=400000......

    区间DP

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,K,F[105][105][105],b[105],Sum[105];
    struct node{
    	int sum,id,val;
    }a[105];
    bool cmp(node a,node b){
    	return a.sum<b.sum;
    }
    int main(){
    	scanf("%d%d",&n,&K);
    	for (int i=1; i<=n; i++) scanf("%d",&a[i].sum);
    	for (int i=1; i<=n; i++) scanf("%d",&a[i].id);
    	for (int i=1; i<=n; i++) b[i]=a[i].id;
    	for (int i=1; i<=n; i++) scanf("%d",&a[i].val);
    	sort(a+1,a+n+1,cmp);
    	sort(b+1,b+n+1);
    	int N=unique(b+1,b+n+1)-b-1;
    	for (int i=1; i<=n; i++) a[i].id=lower_bound(b+1,b+N,a[i].id)-b;
    	for (int i=1; i<=n; i++)
    		for (int j=i; j<=n; j++)
    			for (int k=0; k<=N; k++)
    				F[i][j][k]=1e9;
    	for (int i=1; i<=n; i++) Sum[i]=Sum[i-1]+a[i].val;
    	for (int i=1; i<=n; i++)
    		for (int k=0; k<=N; k++){
    			F[i][i][k]=a[i].val;
    			if (k>a[i].id) F[i][i][k]+=K;
    		}
    	for (int len=1; len<n; len++)
    		for (int i=1; i<n; i++){
    			int j=i+len;
    			if (j>n) break;
    			for (int lim=0; lim<=N; lim++)
    				for (int k=i; k<=j; k++){
    					F[i][j][lim]=min(F[i][j][lim],F[i][k-1][lim]+F[k+1][j][lim]+K+Sum[j]-Sum[i-1]);
    					if (lim<=a[k].id) F[i][j][lim]=min(F[i][j][lim],F[i][k-1][a[k].id]+F[k+1][j][a[k].id]+Sum[j]-Sum[i-1]);
    				}
    		}
    	int ans=1e9;
    	for (int i=0; i<=N; i++) ans=min(ans,F[1][n][i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    A
    B
    A
    A
    B
    C
    有趣的平方和的推导
    一篇写的非常好的匈牙利算法文章
    2014 UESTC Training for Data Structures G
    2014 UESTC Training for Data Structures H
  • 原文地址:https://www.cnblogs.com/silenty/p/9925070.html
Copyright © 2011-2022 走看看