無法拯救我的菜-----焦作網路賽 B. Mathematical Curse
阿新 • • 發佈:2018-12-10
這個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;
}