fzu 2281 Trades [第八届福建省大学生程序设计竞赛 Problem J Trades] [贪心]

来源:互联网 发布:spss mac使用教程 编辑:程序博客网 时间:2024/06/06 00:58

 点击打开题目

题意: 开始有m个金币, 在接下来n天里, ACMeow可以花费ci金币去买一个物品, 也可以以ci的价格卖掉这个物品, 如果它有足够的金币, 每天可以买或卖很多次; 求它在第n天能获得的最大金币数.

分析: (1)如果序列是递增的, 设为c1, c2, c3, c4, ..., cn; 那么如果ACMeow直接在第一天买,最后一天卖, 那么它最后获得的金币数为

如果中间卖(ci)掉一次再买(cj), 最后获得的金币数为


显然ci / cj<= 1, 所以如果是递增序列, 直接在最小的时候买, 最大的时候卖即可.

(2) 如果序列是递减的, 不进行任何交易可以取得最优值

(3) 推广到一般情况, 我们将序列拆分成若干子序列, 假设序列为 1 5 8 5 2 4 6 2 , 可以拆分成1 5 8 | (8) 5 (2) | 24 6 | (6) 2, 通过观察可以发现只需在序列取得极小值的时候买, 在序列取到最大值的时候卖即可. 由于计算时数值较大且中间取模比较麻烦, 所以直接用Java的BigInteger计算比较方便.

 

import java.math.BigInteger;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner cin = new Scanner(System.in);int t = cin.nextInt();int v = 1;while(t-- > 0) {int n = cin.nextInt();BigInteger m = cin.nextBigInteger(), bg = new BigInteger("0");long cc = cin.nextLong(), c = 0;int f = 1;for(int i = 1; i < n; i++) {c = cin.nextLong();if(c > cc && f == 1) {bg = m.divide(new BigInteger(cc + ""));m = m.mod(new BigInteger(cc + ""));f = 0;}if(c < cc && f == 0) {m = m.add(bg.multiply(new BigInteger(cc + "")));f = 1;}cc = c;}if(f == 0) {m = m.add(bg.multiply(new BigInteger(c + "")));}System.out.println("Case #" + v++ + ": " + m.mod(new BigInteger("1000000007")));}cin.close();}}


阅读全文
0 0
原创粉丝点击