1. 程式人生 > >UVa 10700 - Camel trading

UVa 10700 - Camel trading

== 最大值和最小值 一個 計算 maximum 區間 方程 names ()

題目:給你一個僅僅有加法和乘法的計算式,能夠改變計算的優先級,求式子的最大值和最小值。


分析: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;
}

UVa 10700 - Camel trading