[LUOGU] P4342 [IOI1998]Polygon
poj掛了快兩天了。。
洛谷的今日運(yùn)勢真的強(qiáng),說能完成WA的題就能完成。。
咳咳,區(qū)間DP。
思路類似合并果子,不過在維護(hù)f[i][j] (i到j(luò)的最大值) 同時(shí)也要維護(hù)g[i][j] (i到j(luò)的最小值)
為什么呢?考慮把區(qū)間劈成左右兩個(gè)的一次轉(zhuǎn)移:
對(duì)于加法:
1.最大值顯然是左右的最大值之和 max+max
對(duì)于乘法:
1.最大值是左右區(qū)間最大值的乘積 max*max
2.以及最小值的乘積(負(fù)數(shù)情況) min*min
因此要同時(shí)維護(hù)一下最小值才行,具體做法:
對(duì)于加法:
1.最小值是左右最小值之和
對(duì)于乘法:
1.左右最小值的乘積
2.左最小值*右最大值
3.左最大值*右最小值
對(duì)于環(huán)的處理:斷開,復(fù)制一倍
手c數(shù)組真的很危險(xiǎn)。。WA的原因是只初始化[0,n]的數(shù)組,[n+1,n*2]的沒管。
emacs默認(rèn)的兩格縮進(jìn)自己看還行,好像發(fā)上來效果很擠?
#include<iostream> #include<cstdio>using namespace std;const int MAXN=500; const int INF=1<<30; int n;char op[MAXN]; int f[MAXN][MAXN],g[MAXN][MAXN]; int main(){scanf("%d",&n);for(int i=0;i<=2*n;i++){//2*for(int j=0;j<=2*n;j++){//2*f[i][j]=-INF;g[i][j]=INF;}}for(int i=1;i<=n;i++){char s[5];scanf("%s%d",s,&f[i][i]); // cin>>op[i-1]>>f[i][i];g[i][i]=f[i][i];g[i+n][i+n]=f[i+n][i+n]=f[i][i];op[i+n-1]=op[i-1]=s[0];}op[n<<1]=op[0];for(int len=1;len<=n;len++){for(int i=1;i+len<=2*n;i++){//2*int j=i+len;for(int k=i;k<j;k++){if(op[k]=='t'){f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);g[i][j]=min(g[i][j],g[i][k]+g[k+1][j]);}else{f[i][j]=max(f[i][j],max(f[i][k]*f[k+1][j],g[i][k]*g[k+1][j]));g[i][j]=min(g[i][j],min(g[i][k]*g[k+1][j],min(g[i][k]*f[k+1][j],f[i][k]*g[k+1][j])));}}}}int mx=-INF;for(int i=1;i<=n;i++)mx=max(mx,f[i][i+n-1]);cout<<mx<<endl;for(int i=1;i<=n;i++){if(f[i][i+n-1]==mx)cout<<i<<" ";}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/ghostcai/p/9247424.html
總結(jié)
以上是生活随笔為你收集整理的[LUOGU] P4342 [IOI1998]Polygon的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis子查询
- 下一篇: 央行官员:强化虚拟货币监管 遏制境外发币