poj1179 环形+区间dp

因为要用到模,所以左起点设置为0比较好

#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
char c[55];
int val[55],dp_max[55][55],dp_min[55][55];
int cal(char x,int a,int b){if(x==‘t‘)return a+b;return a*b;}

int main(){
    int n;
    while(scanf("%d",&n)==1){
        for(int i=0;i<n;i++) cin>>c[i]>>val[i];
        for(int i=0;i<n;i++) dp_min[i][i]=dp_max[i][i]=val[i];//长度为1的情况
        for(int len=1;len<n;len++)
            for(int l=0;l<n;l++){//枚举左端点
                int MAX=-INF,MIN=INF;
                int r=(l+len)%n;
                for(int k=0;k<len;k++){
                    int p1=(l+k)%n,p2=(l+k+1)%n;
                    MAX=max(MAX,cal(c[p2],dp_max[l][p1],dp_max[p2][r]));
                    MAX=max(MAX,cal(c[p2],dp_min[l][p1],dp_min[p2][r]));
                    MIN=min(MIN,cal(c[p2],dp_max[l][p1],dp_max[p2][r]));
                    MIN=min(MIN,cal(c[p2],dp_min[l][p1],dp_min[p2][r]));
                }
                dp_max[l][r]=MAX;
                dp_min[l][r]=MIN;
            }
        int ans=-INF;
        for(int l=0;l<n;l++){
            int r=(l+n-1)%n;
            ans=max(ans,dp_max[l][r]);
        }
        printf("%d\n",ans);
        for(int l=0;l<n;l++){
            int r=(l+n-1)%n;
            if(dp_max[l][r]==ans) printf("%d ",l+1);
        }
        puts("");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zsben991126/p/10222172.html

时间: 2024-10-09 08:08:32

poj1179 环形+区间dp的相关文章

环形区间DP

区间DP的一般思考方式是:先枚举长度,再枚举开头和结尾,再枚举中间的分割点 环形区间DP一般是把环展开成链后复制成两倍,再做线性的区间DP 1068. 环形石子合并 将 n 堆石子绕圆形操场排放,现要将石子有序地合并成一堆. 规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分. 请编写一个程序,读入堆数 n 及每堆的石子数,并进行如下计算: 选择一种合并石子的方案,使得做 n?1 次合并得分总和最大. 选择一种合并石子的方案,使得做 n?1 次合并得分总和最小. 输入

dp乱写1:环形区间dp(数字游戏)

状态: fmax[i,j]//表示前i个数分成j个部分的最大值 fmin[i,j]//表示前i个数分成j个部分的最小值 边界:fmax[i,1]:=(sum[i] mod 10+10) mod 10(sum[i]为前i个数的总和);fmin[i,1]:=(sum[i] mod 10+10) mod 10; 状态转移方程: fmax[i,j]:=max(fmax[i,j],fmax[k,j-1]*ff(sum[i]-sum[k])); fmin[i,j]:=min(fmin[i,j],fmin[k

能量项链 区间dp

能量项链 时间限制: 1 Sec  内存限制: 64 MB提交: 38  解决: 15[提交][状态][讨论版] 题目描述 每 个天顶星人都随身佩戴着一串能量项链,在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠 子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是天顶星人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠 子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗

石子归并-2:区间DP{环形}

题目描述 Description 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入描述 Input Description 数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数. 输出描述 Output Description 输出共2行,第1行为最小得分,第2行为最大得分. 样例输入

转载+删改:算法讲解之Dynamic Programing —— 区间DP [变形:环形DP]

发现一篇好文,可惜发现有一些地方有排版问题.于是改了一下,并加了一些自己的内容. 原文链接 对区间DP和其变式环形DP的总结. 首先先来例题. 石子归并 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn (wi

区间dp与环形dp

区间dp 常见题型 求区间[1,n]XXXXX后的最大/小值,一般分为无要求或只能/最多分成m段两类 做法 如对分段无要求,设dp[i][j]表示序列中[i,j]的最值,最外层循环区间长度,第二层循环左端点,并能确定右端点,第三层枚举断点: for(rint len = 1;len <= n; ++len) {//如果对len == 1初始化了可从2枚举 for(rint i = 1,j = i + len - 1;j <= n;++i,++j) { for(rint k = i;k <

codevs1154能量项链(环形dp,区间dp)

1154 能量项链 2006年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸

poj1179 区间dp(记忆化搜索写法)有巨坑!

http://poj.org/problem?id=1179 Description Polygon is a game for one player that starts on a polygon with N vertices, like the one in Figure 1, where N=4. Each vertex is labelled with an integer and each edge is labelled with either the symbol + (add

hdu4757 最长回文子序列(区间DP)

http://acm.hdu.edu.cn/showproblem.php?pid=4745 Problem Description Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they planned to play a game with some stones. There were n stones on the ground and they were