zoukankan      html  css  js  c++  java
  • 逆向思维Stock Maximize

    题目出处

    题目描述:

    这个题的意思是:

    给出一段时间内 某个股票的每天的价格

    每天可以进行的操作有:买一股,卖掉所有股,不作为

    问在给定的序列里怎样让价值最大

    数据规模:

    每组数据包含case数 T(<=10)

    每个case中 股票的天数n(<=50000)

    每个股票的价格vi(1<=vi<=100000)

    弱智思路:

    本人的弱智思路是这样的,因为这一个题目被分在了dp分类之中,于是各种蛋疼,dp[i]表示在第i天能达到的最大价值,于是有转移方程:

    dp[i] = dp[j]+v[i]*(i-j+1)-从i-j的股票价格之和(j从0到i)

    然后悠然自得地写了如下代码交了:

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <iostream>
     5 #include <algorithm>
     6 #include <cstring>
     7 using namespace std;
     8 
     9 const int MAXN = 50005;
    10 
    11 int a[MAXN];
    12 long long dp[MAXN];
    13 int n;
    14 
    15 void input(){
    16     cin>>n;
    17     for ( int i = 1; i <= n; i++ ){
    18         cin>>a[i];
    19     }
    20     memset(0,sizeof(dp),0);
    21 }
    22 
    23 long long MAX( long long a, long long b ){
    24     return a > b ? a : b ;
    25 }
    26 
    27 void solve(){
    28     for ( int i = 1; i <= n; i++ ){
    29         long long v = 0;
    30         dp[i] = dp[i-1];
    31         if ( a[i] > a[i-1] ){
    32             for ( int j = i-1; j >= 1; j-- ){
    33                 v += a[j];
    34                 dp[i] = MAX(dp[i],dp[j]-v+a[i]*(i-j));
    35             }
    36         }
    37     }
    38     cout<<dp[n]<<endl;
    39 }
    40 
    41 void deal(){
    42     int t;
    43     cin>>t;
    44     while ( t-- ){
    45         input();
    46         solve();
    47     }
    48 
    49 }
    50 
    51 int main() {
    52     deal();
    53     return 0;
    54 }
    弱爆了

    然后就超时了

    思考了好几天状态压缩的DP,还是各种WA,无奈之下做了伸手党要来了Lazy的代码:

     1  #include <cstdio>
     2 using namespace std;
     3 
     4 const int MAXN = 50000 + 5;
     5 
     6 int N;
     7 int p[MAXN];
     8 
     9 void input() {
    10     scanf("%d", &N);
    11     for (int i=0; i<N; ++i) {
    12         scanf("%d", &p[i]);
    13     }
    14 }
    15 
    16 void solve() {
    17     long long rev = 0;
    18     int max_p = p[N-1];
    19     for (int i=N-1; i>=0; --i) {
    20         if (p[i] < max_p) {
    21             rev += max_p - p[i];
    22         } else {
    23             max_p = p[i];
    24         }
    25     }
    26 
    27     printf("%lld
    ", rev);
    28 }
    29 
    30 int main() {
    31     int t;
    32     scanf("%d", &t);
    33     for (int i=0; i<t; ++i) {
    34         input();
    35         solve();
    36     }
    37 }
    38 快捷回复给:转身/;!孤单
    碉堡了

    然后恍然大悟:

    这题目实际上是一个贪心,最后的价格最大就可以保证总价值最大,因此从后往前扫,并且更新max_p的值。最后输出结果

    反省一下:

    在思考这个题目的时候上述规律我也是发现了的,但是没有犯过头来倒着想,对编码和思考带来了很大的难度,最后还是失败了。以后思维还是灵活一点比较好.

    gg~~

  • 相关阅读:
    winform 通过左右键,或enter键做类似Tab键的功能
    向表中插入查询结果
    创建Oracle job的一些注意事项
    多数据库独立主机的配置
    图形码验证
    JavaScript中的trycatchfinally
    ASP.Net生成后台脚本的问题的解决办法
    10个你未必知道的CSS技巧
    学习JQuery的$.Ready()与OnLoad事件比较[转]
    风雨20年:我所积累的20条编程经验[csdn]
  • 原文地址:https://www.cnblogs.com/qoshi/p/3332798.html
Copyright © 2011-2022 走看看