洛谷Oj-低价购买-最长下降子序列 +最佳方案数统计
2017-09-17 08:58
197 查看
问题描述:
“低价购买”这条建议是在奶牛股票市场取得成功的一半规则。要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买;再低价购买”。每次你购买一支股票,你必须用低于你上次购买它的价格购买它。买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数。你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票。每次购买都必须遵循“低价购买;再低价购买”的原则。写一个程序计算最大购买次数。
这里是某支股票的价格清单:
日期 1 2 3 4 5 6 7 8 9 10 11 12
价格 68 69 54 64 68 64 70 67 78 62 98 87
最优秀的投资者可以购买最多4次股票,可行方案中的一种是:
日期 2 5 6 10
价格 69 68 64 62
AC代码:
解决方法:
加法原理:如果一件事有k个选择,每个选择有a[i]种方案,则一共有Σa[i]种方案。
这道题的难点在于如何判断重复的情况。如果不需要判断重复,只需要sum[i] += sum[j]即可。
既然要判断重复,不妨举个例子:6 5 4 4,有两个最长下降子序列6 5 4 和 6 5 4,二者是相同的情况。
不妨设j < i,a[i] = 4, a[j] = 4。发现特点就是a[i] == a[j]且dp[i] == dp[j]。因为有最长这个条件的保证,6 5 4序列中除去4和6 5 4序列中除去4剩下的部分6 5是完全相同的。
去重只需要将sum[j](或sum[i])赋值为0即可,因为dp方程是由前向后推的,若i和j能继续转移,则必被重复计算,所以sum[i]和sum[j]只能保留一个。
“低价购买”这条建议是在奶牛股票市场取得成功的一半规则。要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买;再低价购买”。每次你购买一支股票,你必须用低于你上次购买它的价格购买它。买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数。你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票。每次购买都必须遵循“低价购买;再低价购买”的原则。写一个程序计算最大购买次数。
这里是某支股票的价格清单:
日期 1 2 3 4 5 6 7 8 9 10 11 12
价格 68 69 54 64 68 64 70 67 78 62 98 87
最优秀的投资者可以购买最多4次股票,可行方案中的一种是:
日期 2 5 6 10
价格 69 68 64 62
AC代码:
int a[5010],dp[5010],sum[5010];//dp[i]代表以第i个元素为结尾的下降子序列的最大长度,sum[i]代表下降子序列的长度为dp[i]的序列的个数 int main() { int n; cin >> n; for(int i = 1; i <= n; ++i) { scanf("%d",&a[i]);//输入 dp[i] = 1;//初始化 sum[i] = 1;//初始化 } for(int i = 1; i <= n; ++i) for(int j = 1; j <= i - 1; ++j) { if(a[j] > a[i])//下降 { if(dp[j] + 1 > dp[i])//如果dp[j] + 1大于当前答案dp[i],就可以转移 { sum[i] = 0;//清0 dp[i] = dp[j] + 1;//状态转移方程 } if(dp[j] + 1 == dp[i]) sum[i] += sum[j];//注意+1是错误的,要加上j的方案数 } if(a[j] == a[i] && dp[j] == dp[i])//判重的语句,这说明两个序列是完全相同的 sum[j] = 0;//清0 } int ans = -inf; for(int i = 1; i <= n; ++i) ans = max(ans,dp[i]);//找出最长的 int cnt = 0; for(int i = 1; i <= n; ++i) if(dp[i] == ans) cnt += sum[i];//计算所有长度为ans的序列的方案数 cout << ans << " " << cnt << endl; return 0; }
解决方法:
加法原理:如果一件事有k个选择,每个选择有a[i]种方案,则一共有Σa[i]种方案。
这道题的难点在于如何判断重复的情况。如果不需要判断重复,只需要sum[i] += sum[j]即可。
既然要判断重复,不妨举个例子:6 5 4 4,有两个最长下降子序列6 5 4 和 6 5 4,二者是相同的情况。
不妨设j < i,a[i] = 4, a[j] = 4。发现特点就是a[i] == a[j]且dp[i] == dp[j]。因为有最长这个条件的保证,6 5 4序列中除去4和6 5 4序列中除去4剩下的部分6 5是完全相同的。
去重只需要将sum[j](或sum[i])赋值为0即可,因为dp方程是由前向后推的,若i和j能继续转移,则必被重复计算,所以sum[i]和sum[j]只能保留一个。
相关文章推荐
- wust oj 1891 低价购买(最长下降子序列+方案数)【模板】
- 洛谷OJ - P1108 - 低价购买(LIS+方案数)
- POJ-1952 最长下降子序列 + 方案数
- 动态规划基础题:低价购买(最长下降子序列)
- poj 1952 BUY LOW, BUY LOWER 最长下降子序列+统计不重复方案数
- 最长不下降子序列 输出方案数
- 最长下降子序列 + 最长的方案数
- hdoj1160 FatMouse's Speed ( STL + 最长下降子序列 /DP)
- 分支限界法解决 二维最长下降序列问题(滑雪场问题)
- tyvj 1208 最长不下降子序列2 求序列b1,b2,b3,…,bm中所有长度(n)最大上升子序列的个数
- 「网络流24题」最长不下降子序列问题
- 【最长下降子序列】北大 POJ 1065 Wooden Sticks
- [线性DP]最长不下降子序列(LIS)
- 关于DP中的最长不下降序列问题分析
- SSL 1459——求最长不下降序列
- 求最长不下降序列
- 最长非降/下降子序列问题(DP)(待续...)
- (ssl1459)求最长不下降序列
- 最长不下降序列(HNOI’97)
- 关于最长下降序列的简单优化