(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
Catalog
Problem:Portal传送门
原题目描述在最下面。
n(2000)
n
(
2000
)
天
m(1e9)
m
(
1
e
9
)
元。每个物品在第
i
i
天的的出售价和买入价都是元。问最后你最多能获得多少钱?一天要么买要么卖。
Solution:
由贪心可得:在物品每次降价前都要把手里的全部卖出,然后降价后全部买入等待下一次卖出。
为什么要在降价前卖出,而不是一涨价就卖出呢?
因为你一直屯着商品肯定可以赚的更多呀。比如
1,2,3,4
1
,
2
,
3
,
4
,你有
3
3
元,当你买入三个元时,你最后可以盈利
9(3×3)
9
(
3
×
3
)
元,但是如果你在
2
2
元时卖出,你还能再买入两个元,最后仅仅盈利
5
5
<script type="math/tex" id="MathJax-Element-233">5</script>元。
问题在于爆longlong了,爆__int128了。所以要么大整数要么Java咯。我这里拿Java写的。你如果要用大整数的话,记得输出答案时用longlong因为要取模输出,1e9+7乘10会爆int。
大整数模板:here
经典原型贪心题:比本题难得多的低买高卖。
AC_Code:
import java.io.*;
import java.math.*;
import java.util.*;
import java.math.BigInteger;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static PrintStream putOut = System.out;
static int MAX_N = 2007;
static BigInteger MOd = BigInteger.valueOf(1000000007);
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int a[] = new int[MAX_N];
int N, M;
int tim = cin.nextInt(),tc=1;
for(int t=0;t<tim;++t){
N = cin.nextInt(); M =cin.nextInt();
for(int i = 1; i <= N; ++i){
a[i]=cin.nextInt();
}
int st = 0, ed = 0, n = N;
BigInteger rem = BigInteger.valueOf(M);
for(int i = 1; i <= N; ++i) {
st = ed = i;
while(ed+1<=N&&a[ed]<=a[ed+1]){
++ed;
}
BigInteger gg = rem.divide(BigInteger.valueOf(a[st]));
BigInteger res = rem.mod(BigInteger.valueOf(a[st]));
if(gg.multiply(BigInteger.valueOf(a[st])).compareTo(rem)>0){
gg.subtract(BigInteger.valueOf(1));
}
gg = gg.multiply(BigInteger.valueOf(a[ed]));
rem = gg.add(res);
i = ed;
}
putOut.println("Case #"+tc+": "+rem.mod(MOd));
tc++;
}
}
}