zoukankan      html  css  js  c++  java
  • 【题解】CF1372E Omkar and Last Floor

    CF1372E Omkar and Last Floor

    ( ext{Solution:})

    首先一个显然的结论是让每一列的 (1) 的个数越多越好。

    证明: ((a+b)^2>a^2+b^2.)

    于是我们应该考虑的是怎么让一列的数的和最大。

    发现我们可以合并两个区间的答案,而数据范围这么小,很容易让人想到 (O(n^3)) 的算法。

    试着考虑区间 (dp:)(f[l][r]) 表示区间 ([l,r]) 的最大平方和。

    然后会发现:这个端点可能跨越了一些段,导致很难转移。

    于是我们更改一下:设 (f[l][r]) 为所有端点都在 ([l,r]) 内的线段组合的最大平方和。那么转移就是:

    [f[l][r]=max{ f[l][k-1]+f[k+1][r]+sum^2[l][r][k]} ]

    其中 (sum[l][r][k]) 代表区间 ([l,r]) 中跨越 (k) 的线段个数。

    考虑怎么处理这个东西:发现对于一个线段 (l,r,kin[l,r],[1,l-1]cup [r+1,m]) 内的端点才会有影响。

    考虑一个以 (l) 为横坐标 (r) 为纵坐标的坐标系,那影响的范围就是一个矩阵。二维前缀和即可。

    有一种神奇的写法:先前缀做出一条线的和,再扫成矩阵的面积。

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,f[101][101];
    int sum[101][101][101];
    struct line{int l,r;}p[101][101];
    int cnt[101];
    inline int Max(int x,int y){return x>y?x:y;}
    int main(){
    	freopen("111.txt","r",stdin);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		int x;
    		scanf("%d",&x);
    		for(int j=1;j<=x;++j){
    			++cnt[i];
    			scanf("%d%d",&p[i][cnt[i]].l,&p[i][cnt[i]].r);
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=cnt[i];++j){
    			int l=p[i][j].l;
    			int r=p[i][j].r;
    			for(int k=l;k<=r;++k)sum[l][r][k]++;
    		}
    	}
    	for(int k=1;k<=m;++k){
    		for(int i=1;i<=m;++i){
    			for(int j=1;j<=m;++j){
    				sum[i][j][k]+=sum[i][j-1][k];
    			}
    		}
    		for(int i=m;i;--i){
    			for(int j=1;j<=m;++j){
    				sum[i][j][k]+=sum[i+1][j][k];
    			}
    		}
    	}
    //	for(int k=1;k<=m;++k){
    //		printf("%d:
    ",k);
    //		for(int i=1;i<=m;++i){
    //			for(int j=1;j<=m;++j)printf("%d ",sum[i][j][k]);
    //			puts("");
    //		}
    //	}
    	for(int i=1;i<=m;++i)f[i][i]=sum[i][i][i]*sum[i][i][i];
    	for(int len=2;len<=m;++len){
    		for(int l=1;l<=m-len+1;++l){
    			int r=l+len-1;
    			for(int k=l;k<=r;++k){
    				f[l][r]=Max(f[l][r],f[l][k-1]+f[k+1][r]+sum[l][r][k]*sum[l][r][k]);
    			}
    		}
    	}
    	printf("%d
    ",f[1][m]);
    	return 0;
    }
    
  • 相关阅读:
    Fiddler界面详解
    Windows平台下Java,tomcat安装与环境配置
    为什么要装Tomcat?
    实例五租房子
    实例四投票
    易犯的PHP小错误及相应分析
    MYSQL数据库错误代码提示汇总
    php mysql_insert_id()
    实例三搜索
    实例二增删改查
  • 原文地址:https://www.cnblogs.com/h-lka/p/15008322.html
Copyright © 2011-2022 走看看