P4342 [IOI1998]Polygon
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4342 [IOI1998]Polygon相关的知识,希望对你有一定的参考价值。
题意:
给你一个n个点的环,第一步,删除其中一条边。随后每一步:
选择一条边连接的两个顶点V1和V2,用边上的运算符计算V1和V2得到的结果来替换这两个顶点。
游戏结束时,只有一个顶点,没有多余的边。
编写一个程序,给定一个多边形,计算最高可能的分数
题解:
在枚举第一步删除哪条边后,剩下的问题就和石头合并很相近了,仍然是在第一步中队两个相邻的元素做某种运算合成一个。我们把被删除的边逆时针方向顶点称为”第一个顶点“。可以得到F[l][r]:表示把第l到第r个顶点合成一个顶点后,顶点上的数值最大是多少
我们注意到题目所给的运算有+和*,对于乘法,有时并不是两个最大数相乘就得到最大值,有可能两个负值乘起来更大,所以我们还需要考虑最小值的情况。因此我们再加一维状态F[l][r][0/1],分别表示表示把第l到第r个顶点合成一个顶点后,顶点上的数值最大是多少,最小值是多少。对于乘法,把各种情况都考虑一边,取最大(最小)。对于加法,不用考虑其他,直接加起来就行
代码:
// Problem: P4342 [IOI1998]Polygon
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4342
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// By Jozky
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
x= 0;
char c= getchar();
bool flag= 0;
while (c < '0' || c > '9')
flag|= (c == '-'), c= getchar();
while (c >= '0' && c <= '9')
x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
if (flag)
x= -x;
read(Ar...);
}
template <typename T> inline void write(T x)
{
if (x < 0) {
x= ~(x - 1);
putchar('-');
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#else
startTime= clock();
freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
endTime= clock();
printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn= 190;
char a[maxn];
int b[maxn];
int f[maxn][maxn][2];
int main()
{
//rd_test();
int n;
scanf("%d", &n);
getchar();
for (int i= 1; i <= 2 * n; i++) {
for (int j= 1; j <= 2 * n; j++) {
f[i][j][0]= -INF_int;
f[i][j][1]= INF_int;
}
}
for (int i= 1; i <= n; i++) {
// getchar();
scanf("%c%d", &a[i], &b[i]);
a[i + n]= a[i];
b[i + n]= b[i];
f[i][i][0]= f[i][i][1]= b[i];
f[i + n][i + n][0]= f[i + n][i + n][1]= b[i];
char ch= getchar();
}
for (int len= 2; len <= n; len++) {
for (int l= 1; l + len - 1 < 2 * n; l++) {
int r= l + len - 1;
for (int k= l; k < r; k++) {
if (a[k + 1] == 'x') {
f[l][r][0]= max(f[l][r][0], f[l][k][0] * f[k + 1][r][0]); //最大乘最大
f[l][r][0]= max(f[l][r][0], f[l][k][1] * f[k + 1][r][1]); //最小乘最小
f[l][r][0]= max(f[l][r][0], f[l][k][1] * f[k + 1][r][0]); //最大乘最小
f[l][r][0]= max(f[l][r][0], f[l][k][0] * f[k + 1][r][1]);
f[l][r][1]= min(f[l][r][1], f[l][k][1] * f[k + 1][r][1]);
f[l][r][1]= min(f[l][r][1], f[l][k][0] * f[k + 1][r][0]);
f[l][r][1]= min(f[l][r][1], f[l][k][1] * f[k + 1][r][0]);
f[l][r][1]= min(f[l][r][1], f[l][k][0] * f[k + 1][r][1]);
}
else if (a[k + 1] == 't') {
f[l][r][0]= max(f[l][r][0], f[l][k][0] + f[k + 1][r][0]);
f[l][r][1]= min(f[l][r][1], f[l][k][1] + f[k + 1][r][1]);
}
}
}
}
int maxx= 0;
for (int i= 1; i <= n; i++) {
maxx= max(maxx, f[i][i + n - 1][0]);
}
printf("%d\\n", maxx);
for (int i= 1; i <= n; i++) {
if (f[i][i + n - 1][0] == maxx) {
printf("%d ", i);
}
}
// cout << maxx << endl;
//Time_test();
}
以上是关于P4342 [IOI1998]Polygon的主要内容,如果未能解决你的问题,请参考以下文章