zoukankan      html  css  js  c++  java
  • POJ1179——Polygon(区间dp)

    传送门

    区间dp不用说了吧

    主要在于要考虑好几种情况

    f[i][j]f[i][j]表示区间iji-j的最大值

    考虑如果是加

    就直接加就是了

    但如果是乘

    却不一定了

    考虑到有可能最大值会由两个最小的负数相乘而来的

    所以我们还要维护一个区间最小值

    而区间最小值的乘有可能由最小值乘最小值,最大值乘最小值(正*负)而来

    所以每次合并区间都要枚举所以可能

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    int f[105][105][2],a[105],op[105],n;//0是最小值,1是最大值
    char ch;
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		cin>>ch;
    		if(ch=='t'){
    			op[i+n-1]=op[i-1]=1;
    		}
    		else op[i+n-1]=op[i-1]=2;
    		a[i]=a[i+n]=read();
    	}
    	for(int i=1;i<=2*n;i++){
    		f[i][i][0]=f[i][i][1]=a[i];
    	}
    	for(int len=1;len<n;len++){
    		for(int l=1;l+len<=2*n;l++){
    			int r=(l+len);
    			int g1=-1e4,g2=1e4;
     			for(int k=l;k<r;k++){
    				if(op[k]==2){
    					g1=max(max(f[l][k][1]*f[k+1][r][1],f[l][k][0]*f[k+1][r][0]),g1);
    					g2=min(min(g2,f[l][k][0]*f[k+1][r][0]),min(f[l][k][1]*f[k+1][r][0],f[l][k][0]*f[k+1][r][1]));
    				}
    				else{
    					g1=max(g1,f[l][k][1]+f[k+1][r][1]);
    					g2=min(g2,f[l][k][0]+f[k+1][r][0]);
    				}
    			}
    			f[l][r][0]=g2;
    			f[l][r][1]=g1;
    		}
    	}
    	int maxn=-1e7,k=0;
    	for(int i=1;i<=n;i++){
    		if(f[i][i+n-1][1]>maxn){
    			k=i,maxn=f[i][i+n-1][1];
    		}
    	}
    	cout<<maxn<<'
    ';
    	for(int i=1;i<=n;i++){
    		if(f[i][i+n-1][1]==maxn){
    			cout<<i<<" ";
    		}
    	}
    }
    
  • 相关阅读:
    闭包 与 装饰器
    Linux常用命令 (二)
    day1 linux常用命令(一)
    📎 .xib
    📎 Emoji 前端转换
    📎 钉钉微应用( 新启项目Weex H5 )
    📎 ROR:常用GEM
    📎 AndroidNative【ING...】
    🆕 ror方法
    安装centos7
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366423.html
Copyright © 2011-2022 走看看