poj.1179 Polygon(区间DP)题解

题目链接:http://poj.org/problem?id=1179
题意:略
思路:通过上一个石子合并的区间DP问题给了我思路(不熟悉\(or\)没写过的同学可以去刷\(Acwing.282\)),石子合并问题中两个相邻石子合并的\(value\)\(sum\),而本题的\(value\)\(A op B\),具体说一下DP方法,第一层枚举区间长度,就类似于一个定长小方块的移动,每次均把相邻的长度为\(Len\)的小方块中的答案处理,含义是指在这个区间内子问题的答案,然后就涉及到状态的转移,因为我们第一层枚举的是长度,所以在我们处理\(Len = i\)时,对于每一个\(Len \in [1,i-1]\)我们均得到了答案,对于\(Len = i\)我们从下标为1开始枚举,每次该区间的答案是由\(f[1][k] op f[k+1][i+1-1] (k \in [1,i+1-1])\)进行得到,区间补充不漏,值得补充的是最外层还要加一个偏移量,因为要枚举第一条删掉的边,这样复杂度为\(O(n^4)\),进一步思考可以得到,创造一个长度为\(2*Len\)的数组,枚举的长度变为\(2*Len\),枚举一遍便可以得到答案,复杂度为\(O(n^3)\),以下是我\(O(n^4)\)的做法
\(Coding:\)


/*************************************************************************
    > File Name: 283.cpp
# Author: Badwoman
# mail: 1194446133@qq.com
    > Created Time: 2021年03月15日 星期一 18时26分21秒
 ************************************************************************/

#include<set>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define bep(i,a,b) for(int i=a;i>=b;--i)
#define lowbit(x) (x&(-x))
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;

template<typename T>void read(T&x){
static char c;static int f;
for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
static char q[65];int cnt=0;
if(x<0)pc('-'),x=-x;
q[++cnt]=x%10,x/=10;
while(x)
	q[++cnt]=x%10,x/=10;
while(cnt)pc(q[cnt--]+'0');
}
const int N = 50+10;
int arr[N],op[N];
int f[N][N];
int v;
int n;
int cal(int i){
	return (v+i)%n;
}
int uf[N][N];
vector<int>ans;
void solve(){

	read(n);
	rep(i,0,n-1){
		char s[3];
		scanf("%s",s);
		read(arr[i]);
		if(s[0] == 't')op[i] = 1;
	}
	int mx = -999999;
	rep(dlt,0,n-1){
		v = dlt;
		memset(f,0xcf,sizeof f);
		memset(uf,0x3f,sizeof f);
		rep(i,1,n)f[cal(i)][cal(i)] = arr[cal(i)],uf[cal(i)][cal(i)] = arr[cal(i)];
		rep(lens,2,n){
			rep(t,0,n-lens){
				int j = t+lens-1;
				rep(k,t,j-1){
					//f[cal(t)][cal(j)] = max(f[cal(t)][cal(j)],op[cal(k+1)] == 0?f[cal(t)][cal(k)]*f[cal(k+1)][cal(j)]:f[cal(t)][cal(k)] + f[cal(k+1)][cal(j)]);
					int h = f[cal(t)][cal(j)],a = f[cal(t)][cal(k)],b = f[cal(k+1)][cal(j)],a1 = uf[cal(t)][cal(k)],b1 = uf[cal(k+1)][cal(j)];
					int h2 = uf[cal(t)][cal(j)];
					if(op[cal(k+1)] == 1){
						h = max(h,a+b);
						h2 = min(h2,a1 + b1);
					}
					else {
						h = max(h,a*b);
						h = max(h,a1*b);
						h = max(h,a*b1);
						h = max(h,a1*b1);
						h2 = min(h2,a*b);
						h2 = min(h2,a*b1);
						h2 = min(h2,a1*b);
						h2 = min(h2,a1*b1);
					}
					f[cal(t)][cal(j)] = h;
					uf[cal(t)][cal(j)] = h2;
				}
			}
		}
		if(mx < f[cal(0)][cal(n-1)]){
			mx = f[cal(0)][cal(n-1)];
			ans.clear();
			ans.pb(dlt+1);
		}
		else if(mx == f[cal(0)][cal(n-1)]){
			mx = f[cal(0)][cal(n-1)];
			ans.pb(dlt+1);
		}
		//mx = max(mx,f[cal(0)][cal(n-1)]);
	}
	write(mx);
	pc('\n');
	rep(i,0,(int)ans.size()-1){
		int p = ans[i];
		write(p);
		if(ans.size()-1 == i)pc('\n');
		else pc(' ');
	}

}

signed main(){
	solve();
	return 0;
}

posted @ 2021-03-15 19:52  xiaodangao  阅读(56)  评论(0编辑  收藏  举报