zoukankan      html  css  js  c++  java
  • [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;
    }
    
    
  • 相关阅读:
    Go开发环境搭建
    es入门小结
    Python操作ES
    mongodb
    RBAC-基于角色的访问控制 django缓存、信号、xadmin使用
    drf序列化群增、群改、群删
    drf过滤、分页、全局异常处理
    VS配置IISExpress外部IP访问
    Oracle中tnsping命令解析
    oracle导入Excel数据文件(大量数据)处理方法
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10754623.html
Copyright © 2011-2022 走看看