题意:把一个多边形去掉一边,再把任意相邻打两个点合并成一个点,求最大值,
注意:两个最小的数相乘可以得到最大的数。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
using namespace std;
#define LL long long
const LL INF =0x3f3f3f3f3f3f3f3f;
int re[59];
int in[59];
int op[59];
int inop[59];
int n;
LL dp[59][59];
LL dp1[59][59];
LL ss(int k,LL a,LL b)
{
if(k==1) return a+b;
else return a*b;
}
int oor()
{
for(int i=0;i<n;i++) for(int j=0;j<n;j++) dp[i][j] = -INF,dp1[i][j] = INF;
for(int i=0;i<n;i++) dp[i][i] = re[i],dp1[i][i] = re[i];
// for(int i=n-1;i>=0;i--) cout<<re[i]<< ' ';cout<<endl;
for(int l=1;l<n;l++)
{
for(int i=n-l-1;i>=0;i--)
{
LL tmp = -INF;
LL tmp1 = INF;
for(int j=0;j<l;j++)
{
tmp = max(tmp,ss(op[i+j],dp[i][i+j],dp[i+j+1][i+l]));
tmp = max(tmp,ss(op[i+j],dp1[i][i+j],dp[i+j+1][i+l]));
tmp = max(tmp,ss(op[i+j],dp[i][i+j],dp1[i+j+1][i+l]));
tmp = max(tmp,ss(op[i+j],dp1[i][i+j],dp1[i+j+1][i+l]));
tmp1 = min(tmp1,ss(op[i+j],dp[i][i+j],dp[i+j+1][i+l]));
tmp1 = min(tmp1,ss(op[i+j],dp1[i][i+j],dp[i+j+1][i+l]));
tmp1 = min(tmp1,ss(op[i+j],dp[i][i+j],dp1[i+j+1][i+l]));
tmp1 = min(tmp1,ss(op[i+j],dp1[i][i+j],dp1[i+j+1][i+l]));
}
dp[i][i+l] = tmp;
dp1[i][i+l] = tmp1;
//cout<<tmp<<' ';
}//cout<<endl;
}
return dp[0][n-1];
}
int anscnt[59];
void solve()
{
int cnt = 0;
LL ans = -INF;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
re[j] = in[(i+j)%n];
op[j] = inop[(i+j)%n];
}
LL k = oor();
if(ans<k)
{
cnt = 0;
anscnt[cnt++] = i;
ans = k;
}else if(ans==k)
{
anscnt[cnt++] = i;
}
}
cout<<ans<<endl;
for(int i=0;i<cnt;i++)
{
if(i) printf(" ");
printf("%d",anscnt[i]+1);
}printf("\n");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while(~scanf("%d",&n))
{
char ch[9];
for(int i=0;i<n;i++)
{
scanf("%s%d",ch,&in[i]);
if(ch[0]=='t') inop[i] = 1;
else inop[i] = 2;
}
int tmp = inop[0];
for(int i=0;i<n;i++) inop[i] = inop[i+1];inop[n-1] = tmp;
solve();
}
return 0;
}
本文探讨了多边形的简化过程,包括去除边和合并顶点的操作,旨在找到最大可能的组合值。通过使用动态规划和最优子结构策略,实现高效的算法优化。
395

被折叠的 条评论
为什么被折叠?



