多边形游戏
#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct mvalue
{
int maxv;
int minv;
int maxj;
int minj;
int maxl , maxr;//0 :子链取最小值,1:子链取最大值
int minl, minr;
}MVA;
class PolyGame
{
public :
PolyGame()
{
cin >> n;
v.assign(n + 1 , - 1);
for (int i = 1; i <= n; i++)
{
int in;
cin >> in;
v[i] = in;
}
op.assign(n + 1, '0');
for (int i = 1; i <= n; i++)
{
char c;
cin >> c;
op[i] = c;
}
//vector<int> is;
//s.push_back(is);
vector<MVA> im;
m.push_back(im);
for (int i = 1; i <= n; i++)
{
//vector<int> is1(n + 1, -1);
//s.push_back(is1);
vector<MVA> im1(n + 1, { -1,-1 , -1,-1});
m.push_back(im1);
}
}
void PolyMax()
{
for (int i = 1; i <= n-1; i++)//链长为1
{
m[i][i] = { v[i],v[i],i ,i,0,0,0,0 };
if ('+' == op[i])
{
m[i][i + 1] = { v[i] + v[i + 1] , v[i] + v[i + 1] , i , i,0,0,0,0 };
}
else
{
m[i][i + 1] = { v[i] * v[i + 1] , v[i] * v[i + 1] , i , i, 0,0,0,0 };
}
}
m[n][n] = { v[n] , v[n] , n , n ,0,0,0,0 };
//链长>= 2
for (int len = 2; len <= n - 1; len++)
{
for (int i = 1; i <= n - len; i++)
{
int j = i + len;
int maxval = -100000;
int minval = 100000;
for (int k = i; k < j; k++)
{
int a = m[i][k].minv;
int b = m[i][k].maxv;
int c = m[k + 1][j].minv;
int d = m[k + 1][j].maxv;
int t1 = maxf(a , b , c , d , k , i , j);
if (maxval < t1)
{
m[i][j].maxv = maxval = t1;
m[i][j].maxj = k;
setMaxFlag(a, b, c, d, k, i, j);
}
int t2 = minf(a, b, c, d, k, i, j);
if (minval > t2)
{
m[i][j].minv = minval = t2;
m[i][j].minj = k;
setMaxFlag(a, b, c, d, k, i, j);
}
}
}
}
}
int maxf(int a , int b ,int c , int d , int k , int i , int j)
{
int d1 = -1;
if ('+' == op[k])
{
d1 = b + d;
}
else
{
d1 = max(a*c, a*d);
d1 = max(d1, b*c);
d1 = max(d1, b*d);
}
return d1;
}
void setMaxFlag(int a, int b, int c, int d, int k, int i, int j)
{
int d1 = m[i][j].maxv;
if ('+' == op[k])
{
m[i][j].maxl = 1;
m[i][j].maxr = 1;
}
else
{
if (d1 == a*c)
{
m[i][j].maxl = 0;
m[i][j].maxr = 0;
}
if (d1 == a*d)
{
m[i][j].maxl = 0;
m[i][j].maxr = 1;
}
if (d1 == b*c)
{
m[i][j].maxl = 1;
m[i][j].maxr = 0;
}
if (d1 == b*d)
{
m[i][j].maxl = 1;
m[i][j].maxr = 1;
}
}
}
void SetMinFlag(int a, int b, int c, int d, int k, int i, int j)
{
int d1 = m[i][j].minv;
if ('+' == op[k])
{
m[i][j].minl = 0;
m[i][j].minr = 0;
}
else
{
if (d1 == a*c)
{
m[i][j].minl = 0;
m[i][j].minr = 0;
}
if (d1 == a*d)
{
m[i][j].minl = 0;
m[i][j].minr = 1;
}
if (d1 == b*c)
{
m[i][j].minl = 1;
m[i][j].minr = 0;
}
if (d1 == b*d)
{
m[i][j].minl = 1;
m[i][j].minr = 1;
}
}
}
int minf(int a, int b, int c, int d, int k , int i ,int j)
{
int d1 = -1;
if ('+' == op[k])
{
d1 = a + c;
}
else
{
d1 = min(a*c, a*d);
d1 = min(d1, b*c);
d1 = min(d1, b*d);
}
return d1;
}
void TraceBackMax(int i, int j)
{
if (i != j)
{
//if(m[i][j].maxj != i && m[i][j].maxj != j
//{
// cout << "(" << i << " , " << m[i][j].maxj << " ) " << op[m[i][j].maxj] << "(" << m[i][j].maxj + 1 << " , " << j << " ) " << endl;
//}
//左子链
cout << "(";
if (m[i][j].maxl == 0)
{
TraceBackMin(i, m[i][j].maxj);//左子链取最小值
}
else
{
TraceBackMax(i, m[i][j].maxj);//左子链取最大值
}
cout << op[m[i][j].maxj];
//右子链
if (m[i][j].maxr == 0)
{
TraceBackMin( m[i][j].maxj+1 , j);//右子链取最小值
}
else
{
TraceBackMax(m[i][j].maxj+1 , j);//右子链取最大值
}
cout << ")";
}
else
{
cout << v[i];
}
}
void TraceBackMin(int i, int j)
{
if (i != j)
{
//cout << "(" << i << " , " << m[i][j].minj << " ) " <<op[m[i][j].minj]<< "(" << m[i][j].minj+1 << " , " << j <<" ) " << endl;
cout << "(";
if (m[i][j].minl == 0)
{
TraceBackMin(i, m[i][j].minj);
}
else
{
TraceBackMax(i, m[i][j].minj);
}
cout << op[m[i][j].minj];
if (m[i][j].minr == 0)
{
TraceBackMin(m[i][j].minj + 1, j);
}
else
{
TraceBackMax(m[i][j].minj + 1, j);
}
cout << ")";
}
else
{
cout << v[i];
}
}
void print()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout <<setw(4) <<m[i][j].maxv << " ";
}
cout << endl;
}
cout << endl;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << setw(4) << m[i][j].maxj << " ";
}
cout << endl;
}
cout << endl;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n ; j++)
{
cout << setw(4) << m[i][j].minv << " ";
}
cout << endl;
}
cout << endl;
for (int i = 1; i <= n ; i++)
{
for (int j = 1; j <= n; j++)
{
cout << setw(4) << m[i][j].minj << " ";
}
cout << endl;
}
cout << endl;
cout << m[1][n].maxv<< endl;
TraceBackMax(1, n);
}
public :
vector<vector<MVA> > m;//链p(i ,j)合并的最值,及断裂处
//vector<vector<int> > s;//链p(i,j)最大值所对应的最后一次合并运算发生处k
vector<char> op;//操作链
vector<int> v;//顶点值
int n;//多边形边数
};
PolyGame PG;
int main()
{
PG.PolyMax();
PG.print();
return 0;
}
默认断开第一条边。。。。
写的有点繁杂。。。。