1. 程式人生 > >[NOIP2000] 乘積最大

[NOIP2000] 乘積最大

嘟嘟嘟

 

我真不信這題在洛谷上是一道黃題,起碼綠題也行啊……

 

dp方程不難,dp[i][j]表示前 i 位用了 j 個乘號時的答案。然後轉移方程我竟然沒想出來(菜的過分)……其實就是列舉第 j 個乘號在哪兒,然後轉移方程就是dp[i][j] = max(dp[i][j], dp[k][j] * num[k +1…i])。

比較坑的是這道題要用高精,於是我現寫了一個高精板子貼了上去。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4
#include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15
#define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 45; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) last = ch, ch = getchar(); 26 while(isdigit(ch)) ans = (ans << 1
) + (ans << 3) + ch - '0', ch = getchar(); 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 const int maxl = 105; 38 struct Big 39 { 40 int a[maxl], len; 41 Big() {Mem(a, 0); len = 0;} 42 void in() 43 { 44 char a1[maxl]; scanf("%s", a1); 45 len = strlen(a1); 46 for(int i = 0; i < len; ++i) a[len - i - 1] = a1[i] - '0'; 47 while(!a[len - 1] && len > 1) len--; 48 } 49 Big getnum(char *s, int L, int R) 50 { 51 Big ret; 52 for(int i = R; i >= L; --i) 53 if(isdigit(s[i])) ret.a[ret.len++] = s[i] - '0'; 54 return ret; 55 } 56 void out() 57 { 58 for(int i = len - 1; i >= 0; --i) write(a[i]); 59 } 60 Big operator + (const Big& oth)const 61 { 62 Big ret; 63 int n = max(len, oth.len) + 1; 64 for(int i = 0; i < n; ++i) 65 { 66 ret.a[i] += a[i] + oth.a[i]; 67 ret.a[i + 1] = ret.a[i] / 10; 68 ret.a[i] %= 10; 69 } 70 while(!ret.a[n - 1] && n > 1) n--; 71 ret.len = n; 72 return ret; 73 } 74 Big operator - (const Big& oth) 75 { 76 Big ret; 77 for(int i = 0; i < len; ++i) 78 { 79 ret.a[i] = a[i] - oth.a[i]; 80 if(ret.a[i] < 0) a[i + 1]--, ret.a[i] += 10; 81 } 82 ret.len = len; 83 while(!ret.a[ret.len - 1] && ret.len > 1) ret.len--; 84 return ret; 85 } 86 Big operator * (const Big& oth)const 87 { 88 Big ret; 89 for(int i = 0; i < len; ++i) 90 for(int j = 0; j < oth.len; ++j) 91 { 92 ret.a[i + j] += a[i] * oth.a[j]; 93 ret.a[i + j + 1] += ret.a[i + j] / 10; 94 ret.a[i + j] %= 10; 95 } 96 ret.len = len + oth.len; 97 while(!ret.a[ret.len - 1] && ret.len > 1) ret.len--; 98 return ret; 99 } 100 Big operator / (const int& x)const 101 { 102 Big ret; 103 int res = 0; 104 for(int i = len - 1; i >= 0; --i) 105 { 106 res *= 10; res += a[i]; 107 ret.a[ret.len++] = res / x; 108 res %= x; 109 } 110 reverse(ret.a, ret.a + ret.len); 111 while(!ret.a[ret.len - 1] && ret.len > 1) ret.len--; 112 return ret; 113 } 114 int operator % (const int& mod)const 115 { 116 int res = 0; 117 for(int i = len - 1; i >= 0; --i) res = res * 10 + a[i], res %= mod; 118 return res; 119 } 120 bool operator < (const Big& oth)const 121 { 122 if(len != oth.len) return len < oth.len; 123 for(int i = len - 1; i >= 0; --i) 124 if(a[i] != oth.a[i]) return a[i] < oth.a[i]; 125 return 0; 126 } 127 }; 128 129 Big Bmax(Big A, Big B) 130 { 131 if(A.len > B.len) return A; 132 if(B.len > A.len) return B; 133 for(int i = A.len - 1; i >= 0; --i) 134 { 135 if(A.a[i] > B.a[i]) return A; 136 if(B.a[i] > A.a[i]) return B; 137 } 138 return A; 139 } 140 141 int n, m; 142 char a[maxn]; 143 Big dp[maxn][10]; 144 145 int main() 146 { 147 n = read(); m = read(); 148 scanf("%s", a); 149 for(int i = 0; i < n; ++i) dp[i][0] = dp[i][0].getnum(a, 0, i); 150 for(int i = 1; i < n; ++i) 151 for(int j = 1; j <= m && j <= i; ++j) 152 for(int k = 0; k < i; ++k) 153 { 154 Big tp = tp.getnum(a, k + 1, i); 155 if(dp[i][j] < dp[k][j - 1] * tp) 156 dp[i][j] = dp[k][j - 1] * tp; 157 } 158 dp[n - 1][m].out(); 159 return 0; 160 }
View Code