ACM-ICPC 2018 焦作賽區網路預賽 B. Mathematical Curse(dp)
阿新 • • 發佈:2018-12-10
樣例輸入
3
2 1 5
2 3
/
3 2 1
1 2 3
++
4 4 5
1 2 3 4
+-*/
樣例輸出
2
6
3
題意: n個數字,m個運算子(+-*/),從n個數字中選擇m個數字,按原陣列順序與k進行運算,使得最後結果最大
思路:對dp一竅不通,隊友過的,事後理解了再補上做法,先放隊友的程式碼dp[i][j]表示第i個數字,j個操作符下的結果
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; typedef long long ll; const ll mod=1e9+7; ll calc(ll x,char op,ll y) { switch(op){ case '+': return x+y; case '-': return x-y; case '*': return x*y; case '/': return x/y; } } int T,n,m; ll k; ll a[1005],dp[1005][6],pd[1005][6]; char f[15]; int main() { scanf("%d",&T); while(T--) { memset(dp,0x80,sizeof(dp)); memset(pd,0x3f,sizeof(pd)); scanf("%d %d %lld",&n,&m,&k); for(int i=1;i<=n;i++) scanf("%lld",a+i); scanf("%s",f+1); for(int i=0;i<=n;i++) pd[i][0]=dp[i][0]=k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ if(i<=m&&j>i)break; dp[i][j]=max(dp[i-1][j],calc(dp[i-1][j-1],f[j],a[i])); pd[i][j]=min(pd[i-1][j],calc(pd[i-1][j-1],f[j],a[i])); dp[i][j]=max(dp[i][j],calc(pd[i-1][j-1],f[j],a[i])); pd[i][j]=min(pd[i][j],calc(dp[i-1][j-1],f[j],a[i])); } printf("%lld\n",dp[n][m]); } return 0; }