标签:blog io ar os 使用 sp for on 2014
题目:给你一个只有加法和乘法的计算式,可以改变计算的优先级,求式子的最大值和最小值。分析:dp,区间动态规划。矩阵想成类似物。
状态:f(s,e)为区间[s, e]上计算式最大值,t(s,e)为区间[s, e]上计算式最小值;
方程:f(s,e)= max(f(s,k)+ f(k+1,e)) { s ≤ k ≤ e };
t(s,e)= min(t(s,k)+ f(k+1,e)) { s ≤ k ≤ e }。
说明:使用long long防止溢出(20^12)。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; char buf[101]; char oper[15]; int data[15]; long long f[15][15],t[15][15]; int main() { int n,count; while (~scanf("%d",&n)) while (n --) { scanf("%s",buf); data[count = 1] = 0; for (int i = 0 ; buf[i] ; ++ i) if (buf[i] == '*' || buf[i] == '+') { oper[count] = buf[i]; data[++ count] = 0; }else { data[count] *= 10; data[count] += buf[i]-'0'; } for (int i = 1 ; i <= count ; ++ i) f[i][i] = t[i][i] = data[i]; for (int l = 2 ; l <= count ; ++ l) { for (int s = 1 ; s+l-1 <= count ; ++ s) { f[s][s+l-1] = 0LL; t[s][s+l-1] = 5000000000000000LL; for (int k = s ; k < s+l-1 ; ++ k) { if (oper[k] == '+' && f[s][s+l-1] < f[s][k]+f[k+1][s+l-1]) f[s][s+l-1] = f[s][k]+f[k+1][s+l-1]; if (oper[k] == '*' && f[s][s+l-1] < f[s][k]*f[k+1][s+l-1]) f[s][s+l-1] = f[s][k]*f[k+1][s+l-1]; if (oper[k] == '+' && t[s][s+l-1] > t[s][k]+t[k+1][s+l-1]) t[s][s+l-1] = t[s][k]+t[k+1][s+l-1]; if (oper[k] == '*' && t[s][s+l-1] > t[s][k]*t[k+1][s+l-1]) t[s][s+l-1] = t[s][k]*t[k+1][s+l-1]; } } } printf("The maximum and minimum are %lld and %lld.\n",f[1][count],t[1][count]); } return 0; }
标签:blog io ar os 使用 sp for on 2014
原文地址:http://blog.csdn.net/mobius_strip/article/details/41281305