A Za, A Za, Fighting...

坚信:勤能补拙

PKU 1179 Polygon

问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1179

思路:
这题输在了对原题目的理解和分析上,没能成功地走出第一步:
                                                      将原题解析成对于表达式的求解
把缺了一条边的多边形展开成直线就是一个表达式
注意:为了求乘法,必须同时保存最大值和最小值

f[i][j]记录表达式中从顶点i到顶点j这段子表达式的值

动态规划的思想类似于矩阵连乘

参考:
http://hi.baidu.com/xiehuixb/blog/item/575ec81e221466c1a786699e.html

代码:
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define MAX_LEN 51
 5 #define INF 9223372036854775807LL
 6 #define maximal(a, b) ((a)>(b) ? (a) : (b))
 7 #define minimal(a, b) ((a)<(b) ? (a) : (b))
 8 char operand[MAX_LEN][2];
 9 int operators[MAX_LEN];
10 int n, ans_len, ans[MAX_LEN];
11 long long int rt, max[MAX_LEN][MAX_LEN], min[MAX_LEN][MAX_LEN];
12 
13 /*
14  * when it comes to: '+'
15  * max[i][j] = maximal(max[i][k] + max[k+1][j])
16  * min[i][j] = minimal(min[i][k] + min[k+1][j])
17  *
18  * when it comes to: '*'
19  * max[i][j] = maximal(max[i][k]*max[k+1][j], max[i][k]*min[k+1][j], min[i][k]*max[k+1][j], min[i][k]*min[k+1][j])
20  * min[i][j] = minimal(max[i][k]*max[k+1][j], max[i][k]*min[k+1][j], min[i][k]*max[k+1][j], min[i][k]*min[k+1][j])
21  *
22  * i<=k<j
23  */
24 void
25 solve(char *opd, int *ops, int del_edge)
26 {
27     int i, j, k, len;
28     for(i=1; i<=n; i++)
29         max[i][i] = min[i][i] = ops[i];
30     for(len=2; len<=n; len++) {
31         for(i=1; i<=n-len+1; i++) {
32             j = i+len-1;
33             max[i][j] = -INF;
34             min[i][j] = INF;
35             for(k=i; k<j; k++) {
36                 if(opd[k] == 't') {
37                     max[i][j] = maximal(max[i][j], max[i][k]+max[k+1][j]);
38                     min[i][j] = minimal(min[i][j], min[i][k]+min[k+1][j]);
39                 } else { /* opd[k] == 'x' */
40                     max[i][j] = maximal(max[i][j], max[i][k]*max[k+1][j]);
41                     max[i][j] = maximal(max[i][j], max[i][k]*min[k+1][j]);
42                     max[i][j] = maximal(max[i][j], min[i][k]*max[k+1][j]);
43                     max[i][j] = maximal(max[i][j], min[i][k]*min[k+1][j]);
44 
45                     min[i][j] = minimal(min[i][j], max[i][k]*max[k+1][j]);
46                     min[i][j] = minimal(min[i][j], max[i][k]*min[k+1][j]);
47                     min[i][j] = minimal(min[i][j], min[i][k]*max[k+1][j]);
48                     min[i][j] = minimal(min[i][j], min[i][k]*min[k+1][j]);
49                 }
50             }
51         }
52     }
53     if(max[1][n] >= rt) {
54         if(max[1][n] == rt)
55             ans[ans_len++= del_edge;
56         else {
57             rt = max[1][n];
58             ans_len = 0;
59             ans[ans_len++= del_edge;
60         }
61     }
62 }
63 
64 int
65 main(int argc, char **argv)
66 {
67     int i, j, k;
68     char tmpopd[MAX_LEN];
69     int tmpops[MAX_LEN];
70     while(scanf("%d"&n) != EOF) {
71         for(i=1; i<=n; i++)
72             scanf("%s%d", operand[i], operators+i);
73         rt = -INF;
74         ans_len = 0;
75         for(i=1; i<=n; i++) {
76             for(j=i%n+1, k=1; j!=i; j=j%n+1, k++)
77                 tmpopd[k] = operand[j][0];
78             tmpopd[k] = '\0';
79             tmpops[1= operators[i];
80             for(j=i%n+1, k=2; j!=i; j=j%n+1, k++)
81                 tmpops[k] = operators[j];
82             solve(tmpopd, tmpops, i);
83         }
84         printf("%lld\n", rt);
85         for(i=0; i<ans_len; i++)
86             printf("%d ", ans[i]);
87         printf("\n");
88     }
89 }

posted on 2010-08-17 13:51 simplyzhao 阅读(131) 评论(0)  编辑 收藏 引用 所属分类: C_动态规划


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2011年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜