题目描述:
这个题的意思是:
给出一段时间内 某个股票的每天的价格
每天可以进行的操作有:买一股,卖掉所有股,不作为
问在给定的序列里怎样让价值最大
数据规模:
每组数据包含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\n", 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~~