题目描述
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生感到反感,不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
输入
本题目包含多组测试,请处理到文件结束。在每个测试的第一行,有两个正整数 N 和 M分别代表学生的数目和操作的数目。学生ID编号分别从1编到N。第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数ai代表ID为i的学生的成绩。接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
输出
输出相应的询问。
样例输入
样例输出
提示
【数据说明】
对于 30%的数据,0 < n < 1,00,0 < m < 10,00;
对于 60%的数据,0 < n < 1,000,0 < m < 1000;
对于 100%的数据,0 < n < 200,000,0 < m < 50000,0 <=ai<=2^31-1。
假设F(N,K)是字符串前N位插入K个乘号后所能得到的最大值,考虑一下F(N,K)与F(N-1,K)、F(N-1,K-1)的关系?
附例子:
312:当N=3, K=1时,从N=1, K=0开始推导
F(1, 0) = 3
F(2, 0) = 31
F(3, 1) = max(F(1, 0)*12, F(2,0)*2) = max(36, 62) = 62
31245:N=5, K=2,还是从F(1, 0)开始推导
F(1, 0) = 3
F(2, 0) = 31
F(3, 0) = 312
F(2, 1) = 3*1 = 3
F(3, 1) = max(F(1, 0) * 12, F(2, 0) * 2) = max(36, 62) = 62
F(4, 1) = max(F(1, 0) * 124, F(2, 0) * 24, F(3, 0) * 4) = max(372, 744, 1248) = 1248
F(5, 2) = max(F(2, 1) * 245, F(3, 1) * 45, F(4, 1) * 5) = max(735, 2790, 6240) = 6240
动态规划方程:
设A[I,Num] B[I,Num] 是第一个数字到第I个数字中加Num个乘号所得的最大值 ,s[k,I]表示从第k位到第I位的一个数字
那么
B[I,Num]=max(A[k,Num-1]*S[k+1,I]) 1+Num-1 <=k <=I;
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n,k;
char ch[45];
cin>>n>>k;
scanf("%s",ch+1);
int f[45],asum=0;
for (int i=1;i<=n-k;i++) //不插入*时的情况
{
asum=asum*10+ch[i]-'0';
f[i]=asum;
}
for (int tk=1;tk<=k;tk++)
{
for (int tn=n-k+tk;tn>=tk+1;tn--)
{
f[tn]=-1;
char temp[45];
for (int j=tk;j<=tn-1;j++) //找寻f[tn]最大值
{
memcpy(temp,ch+j+1,tn-j);
temp[tn-j]=0;
if (f[tn] < f[j]*atoi(temp)) f[tn]=f[j]*atoi(temp); //atoi()函数 把字符串转换为int型数字
}
}
}
printf("%d\n",f[n]);
return 0;
}