poj1179

 1 //Accepted    244 KB    0 ms
 2 //区间dp
 3 //石子合并模型
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <iostream>
 7 using namespace std;
 8 const int imax_n = 105;
 9 const int Pinf = 100000000;
10 const int Ninf = -100000000;
11 int dp_min[imax_n][imax_n];
12 int dp_max[imax_n][imax_n];
13 int a[imax_n];
14 char s[imax_n][3];
15 int n;
16 int max(int a,int b)
17 {
18     return a>b?a:b;
19 }
20 int min(int a,int b)
21 {
22     return a<b?a:b;
23 }
24 int cal(int a,int b,char s[])
25 {
26     if (s[0]==‘t‘) return a+b;
27     return a*b;
28 }
29 void Dp()
30 {
31     for (int i=1;i<2*n;i++)
32     dp_max[i][i]=dp_min[i][i]=a[i];
33     for (int l=2;l<=n;l++)
34     {
35         for (int i=1;i<2*n;i++)
36         {
37             int j=i+l-1;
38             if (j>=2*n) break;
39             dp_max[i][j]=Ninf;
40             dp_min[i][j]=Pinf;
41             for (int k=i;k<=j-1;k++)
42             {
43                 dp_max[i][j]=max(dp_max[i][j],cal(dp_max[i][k],dp_max[k+1][j],s[k+1]));
44                 dp_max[i][j]=max(dp_max[i][j],cal(dp_min[i][k],dp_min[k+1][j],s[k+1]));
45                 dp_min[i][j]=min(dp_min[i][j],cal(dp_min[i][k],dp_min[k+1][j],s[k+1]));
46                 dp_min[i][j]=min(dp_min[i][j],cal(dp_max[i][k],dp_min[k+1][j],s[k+1]));
47                 dp_min[i][j]=min(dp_min[i][j],cal(dp_min[i][k],dp_max[k+1][j],s[k+1]));
48             }
49         }
50     }
51     int ans=Ninf;
52     for (int i=1;i<=n;i++)
53     ans=max(ans,dp_max[i][i+n-1]);
54     printf("%d\n",ans);
55     int flag=0;
56     for (int i=1;i<=n;i++)
57     {
58         if (dp_max[i][i+n-1]==ans)
59         {
60             if (flag==0)
61             {
62                 printf("%d",i);
63                 flag=1;
64             }
65             else
66             {
67                 printf(" %d",i);
68             }
69         }
70     }
71     printf("\n");
72 }
73 int main()
74 {
75     while (scanf("%d",&n)!=EOF)
76     {
77         for (int i=1;i<=n;i++)
78         scanf("%s%d",s[i],&a[i]);
79         for (int i=1;i<n;i++)
80         {
81             a[n+i]=a[i];
82             strcpy(s[n+i],s[i]);
83         }
84         Dp();
85     }
86     return 0;
87 }

poj1179

时间: 2024-10-12 02:43:53

poj1179的相关文章

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

POJ1179——Polygon

Polygon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4975   Accepted: 2090 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 int

[POJ1179]Polygon

http://poj.org/problem?id=1179 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘积)标记. 第一步,删除其中一条边.随后每一步: 选择一条边连接的两个顶点V1和V2,用边上的运算符计算V1和V2得到的结果来替换这两个顶点. 游戏结束时,只有一个顶点,没有多余的边. 如图所示,玩家先移除编号为3的边.之后,玩家选择计算编号为1的边,然后计算编号为4的边,最后,计算编号为2的边.结果是0. (翻

poj1179 Polygon【区间DP】

Polygon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:6633   Accepted: 2834 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 inte

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;} in

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

Mark一下, dp状态转移方程写对,但是写代码都错,poj 1651 poj 1179

dp题: 1.写状态转移方程; 2.考虑初始化边界,有意义的赋定值,还没计算的赋边界值: 3.怎么写代码自底向上计算最优值 今天做了几个基础dp,全部是dp方程写对但是初始化以及计算写错 先是poj 1651 其实就是个赤裸裸的矩阵连乘,dp方程很容易写出 dp[i][j]=min(dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j],dp[i][j]); 先贴两个个二逼的代码,mark下自己多么的二逼: 二逼一:在计算的时候使用了还没有算出来的值,模拟下就知道第一重循环里算dp

#6:年兽礼包——6

石子合并,入门区间dp 1 #include <cstdio> 2 #include <cstring> 3 #define maxn 305 4 #define min(a, b) a < b ? a : b 5 6 int n; 7 int sum[maxn]; 8 int f[maxn][maxn]; 9 10 int main() { 11 memset(f, 0x3f, sizeof(f)); 12 scanf("%d", &n); 13