[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

 

posted @ 2018-10-31 23:02  mrclr  阅读(292)  评论(0编辑  收藏  举报