P4342 [IOI1998]Polygon

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4342 [IOI1998]Polygon相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

P4342 [IOI1998]Polygon

P4342 [IOI1998]Polygon 区间dp+断环成链

IOI1998Polygon

洛谷 P4342 / poj 1179 Polygon

ioi1998 Picture

推荐电影 历年佳片有约电影 1998-2007