您的位置:首页 > 其它

QUST日常训练(1)乘积最大

2016-04-02 16:18 323 查看

题目描述

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。

这让很多学生感到反感,不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

输入

本题目包含多组测试,请处理到文件结束。在每个测试的第一行,有两个正整数 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。

输出

输出相应的询问。

样例输入

5 61 2 3 4 5Q 1 5U 3 6Q 3 4Q 4 5U 2 9Q 1 5

样例输出

5659

提示

【数据说明】

对于 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。

分析:DP问题(参考大神代码)

假设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
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: