• [IOI1998]Polygon


    很早就看到这题了...但因为有个IOI标志,拖到现在才做

    由于是以前在书上看到的,就没有想过其他算法,直接区间DP了...

    方程式也挺好想的

    跟我们平时做数学题求几个数乘积最大差不多

    最大的*最大的

    最小的*最小的(可能是负数)

    这样两种情况

    由于求最大中要用到最小值,我们在维护最大同时维护最小

    最小的*最小的

    最小的*最大的

    也是两种情况

    再考虑加法

    最大:最大+最大

    最小:最小+最小

    各有一种情况

    Tip 上面所述的类似于最大*最大都是左区间最大/小 和右区间最大/小

    表达起来大概是这样的

    	for(int len=2;len<=n;++len){
    		for(int i=1;i+len-1<=2*n;++i){
    			int j=i+len-1;
    			for(int k=i;k<j;++k){
    				if(opt[k+1]=='x')
    					cmax(dpd[i][j],dpd[i][k]*dpd[k+1][j],dpx[i][k]*dpx[k+1][j]),
    					cmin(dpx[i][j],dpd[i][k]*dpx[k+1][j],dpx[i][k]*dpd[k+1][j],dpx[i][k]*dpx[k+1][j]);
    				else
    					cmin(dpx[i][j],dpx[i][k]+dpx[k+1][j]),
    					cmax(dpd[i][j],dpd[i][k]+dpd[k+1][j]);
    			}
    		}
    	}
    

    最后的代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define inf (0x7fffffff)
    #define writeln(x)  write(x),puts("")
    #define writep(x)   write(x),putchar(' ')
    using namespace std;
    inline int read(){
    	int ans=0,f=1;char chr=getchar();
    	while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
    	while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    	return ans*f;
    }void write(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }int n,a[155],dpx[155][155],dpd[155][155],ans=-inf;char opt[55];
    inline void cmin(int &a,int b){if(b<a) a=b;}
    inline void cmin(int &a,int b,int c){cmin(a,b),cmin(a,c);}
    inline void cmin(int &a,int b,int c,int d){cmin(a,b,c),cmin(a,d);}
    inline void cmax(int &a,int b){if(a<b)a=b;}
    inline void cmax(int &a,int b,int c){cmax(a,b),cmax(a,c);}
     
    int main(){
    	n=read();
    	for(register int i=1;i<=n;++i) cin>>opt[i]>>a[i];
    	for(register int i=1;i<=n;++i) opt[i+n]=opt[i],a[i+n]=a[i];
    	for(int i=1;i<=n*2;++i)
    		for(int j=1;j<=n*2;++j)
    			(i==j)?(dpx[i][i]=dpd[i][i]=a[i]):(dpd[i][j]=-inf,dpx[i][j]=inf);
    	for(int len=2;len<=n;++len){
    		for(int i=1;i+len-1<=2*n;++i){
    			int j=i+len-1;
    			for(int k=i;k<j;++k){
    				if(opt[k+1]=='x')
    					cmax(dpd[i][j],dpd[i][k]*dpd[k+1][j],dpx[i][k]*dpx[k+1][j]),
    					cmin(dpx[i][j],dpd[i][k]*dpx[k+1][j],dpx[i][k]*dpd[k+1][j],dpx[i][k]*dpx[k+1][j]);
    				else
    					cmin(dpx[i][j],dpx[i][k]+dpx[k+1][j]),
    					cmax(dpd[i][j],dpd[i][k]+dpd[k+1][j]);
    			}
    		}
    	}
    	for(int i=1;i<=n;++i) cmax(ans,dpd[i][i+n-1]);writeln(ans);
    	for(int i=1;i<=n;i++) if(dpd[i][i+n-1]==ans) writep(i);
    	return 0;
    }
    
    
  • 相关阅读:
    SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版)
    Vue+Video.js播放m3u8视频流(海康威视摄像头+RTMP服务+FFmpeg)
    Vue+Openlayers中实现地图旋转
    Vue中实现检测当前是否为IE模式(极速模式还是兼容模式)
    Vue+Openlayer使用overlay实现弹窗弹出显示与关闭
    Vue+Openlayers实现显示图片并分优先级多图层加载
    Vue+Openlayer使用Draw实现交互式绘制线段
    ActionScriopt 产生随机颜色
    在AS3中格式化日期
    ArcGis For Flex 之 QueryTask地理坐标展现【原创】
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10754623.html
Copyright © 2020-2023  润新知