1. 程式人生 > >無法拯救我的菜-----焦作網路賽 B. Mathematical Curse

無法拯救我的菜-----焦作網路賽 B. Mathematical Curse

這個dp是個簡單dp,賽場上思路是對的,負負得正,說明當前最大值可以來自前面的最大值或者最小值。。。。這個沒想到,還是菜。。。。。。 dp[i][j]表示選到了第i個數時用了j個運算子,觀察發現,一個數只能由他前一個狀態的最大值或最小值轉移過來(因為乘上一個負數會使最小的數變最大),所以我們同時維護最大最小。 然後轉移就行了 轉移方程:dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - 1] 運算元 a[i]); 要注意i - 1 >= y 和i == y

#include<bits/stdc++.h>
using namespace
std; typedef long long LL; const int inf = 0x3f3f3f3f; LL MAX[1005][8]; LL MIN[1005][8]; LL a[1005]; char f[15]; LL jisuan(LL k,char s,LL val) { LL x; switch(s) { case '+':x = k + val;break; case '-':x = k - val;break; case '*':x = k * val;break; case '/':x = k / val;break
; } return x; } int main() { int t; scanf("%d",&t); while(t--) { int n,m,k; scanf("%d %d %d",&n,&m,&k); for(int i = 1;i <= n;++i) { scanf("%lld",&a[i]); } scanf("%s",f); memset(MAX,0,sizeof
(MAX)); memset(MIN,0,sizeof(MIN)); for(int i = 0;i <= n;++i) { MIN[i][0] = k; MAX[i][0] = k; } for(int i = 1;i <= n;++i) { for(int j = 1;j <= m;++j) { if(i >= j){ LL x = jisuan(MAX[i - 1][j - 1],f[j - 1],a[i]); LL y = jisuan(MIN[i - 1][j - 1],f[j - 1],a[i]); LL maxx = max(x,y); LL minn = min(x,y); if(i == j){ MAX[i][j] = maxx; MIN[i][j] = minn; continue; } MAX[i][j] = max(MAX[i - 1][j],maxx); MIN[i][j] = min(MIN[i - 1][j],minn); } } } LL MAXX = -inf; for(int i = m;i <= n;++i) MAXX = max(MAXX,MAX[i][m]); printf("%lld\n",MAXX); } return 0; }