(复习)poj 1952 最长下降子序列—— dp+方案个数
2014-09-17 16:34
381 查看
BUY LOW, BUY LOWER
Description
The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice:
Each time you buy a stock, you must purchase it at a lower price than the previous time you bought it. The more times you buy at a lower price than before, the better! Your goal is to see how many times you can continue purchasing at ever lower prices.
You will be given the daily selling prices of a stock (positive 16-bit integers) over a period of time. You can choose to buy stock on any of the days. Each time you choose to buy, the price must be strictly lower than the previous time you bought stock. Write
a program which identifies which days you should buy stock in order to maximize the number of times you buy.
Here is a list of stock prices:
The best investor (by this problem, anyway) can buy at most four times if each purchase is lower then the previous purchase. One four day sequence (there might be others) of acceptable buys is:
Input
* Line 1: N (1 <= N <= 5000), the number of days for which stock prices are given
* Lines 2..etc: A series of N space-separated integers, ten per line except the final line which might have fewer integers.
Output
Two integers on a single line:
* The length of the longest sequence of decreasing prices
* The number of sequences that have this length (guaranteed to fit in 31 bits)
In counting the number of solutions, two potential solutions are considered the same (and would only count as one solution) if they repeat the same string of decreasing prices, that is, if they "look the same" when the successive prices are compared. Thus,
two different sequence of "buy" days could produce the same string of decreasing prices and be counted as only a single solution.
Sample Input
Sample Output
本道题的最大收获就是知道了——
求解不重复的方案个数其实不一定需要对整个路径进行还原一一比较,在某些情况下可以一边dp一边排除
题目大意:
RT
思路&反省:
这道题是dp求解LIS的升级版,多了一个求解方案个数的提问。
(1)一开始还想着用一个配合着dp的同等大小的 set<string> 数组来去重求解,爆空间了无疑
下面是代码
(2)
后来上网看了下他人的解法。
发现的确是高。其实并不需要记录每一条dp路径,而可以用一个path数组记录与dp相对应的法案数,
在dp过程中,将之前的,价格与当下相等的那个path值直接赋0(因为当前的path值一定大于等于之前的path),
这样之后不会重复加上方案数了。
自己在真正接受(原来只是看了一眼就自己敲了)这种想法之前还是自己敲了一个很难改的WA了的代码
详细错误在下面的代码注释里
下面是ac代码
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 8466 | Accepted: 2930 |
The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice:
"Buy low; buy lower"
Each time you buy a stock, you must purchase it at a lower price than the previous time you bought it. The more times you buy at a lower price than before, the better! Your goal is to see how many times you can continue purchasing at ever lower prices.
You will be given the daily selling prices of a stock (positive 16-bit integers) over a period of time. You can choose to buy stock on any of the days. Each time you choose to buy, the price must be strictly lower than the previous time you bought stock. Write
a program which identifies which days you should buy stock in order to maximize the number of times you buy.
Here is a list of stock prices:
Day 1 2 3 4 5 6 7 8 9 10 11 12 Price 68 69 54 64 68 64 70 67 78 62 98 87
The best investor (by this problem, anyway) can buy at most four times if each purchase is lower then the previous purchase. One four day sequence (there might be others) of acceptable buys is:
Day 2 5 6 10 Price 69 68 64 62
Input
* Line 1: N (1 <= N <= 5000), the number of days for which stock prices are given
* Lines 2..etc: A series of N space-separated integers, ten per line except the final line which might have fewer integers.
Output
Two integers on a single line:
* The length of the longest sequence of decreasing prices
* The number of sequences that have this length (guaranteed to fit in 31 bits)
In counting the number of solutions, two potential solutions are considered the same (and would only count as one solution) if they repeat the same string of decreasing prices, that is, if they "look the same" when the successive prices are compared. Thus,
two different sequence of "buy" days could produce the same string of decreasing prices and be counted as only a single solution.
Sample Input
12 68 69 54 64 68 64 70 67 78 62 98 87
Sample Output
4 2
本道题的最大收获就是知道了——
求解不重复的方案个数其实不一定需要对整个路径进行还原一一比较,在某些情况下可以一边dp一边排除
题目大意:
RT
思路&反省:
这道题是dp求解LIS的升级版,多了一个求解方案个数的提问。
(1)一开始还想着用一个配合着dp的同等大小的 set<string> 数组来去重求解,爆空间了无疑
下面是代码
#include <iostream> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <functional> #define maxn 5005 using namespace std; int a[maxn]; int dp[maxn]; int main() { int n; while(scanf("%d",&n)!=EOF){ set<string> G[maxn]; for(int i=0;i<n;i+=1){ scanf("%d",&a[i]); dp[i]=1; char c[10]; sprintf(c, "%d", a[i]); string news(c); G[i].insert(news); } int res=0; for(int i=0;i<n;i+=1){ int maxx=0; for(int j=0;j<i;j+=1){ if(a[j]>a[i]&&dp[j]+1>dp[i]){ dp[i]=dp[j]+1; maxx=max(maxx,dp[j]); } } for(int j=0;j<i;j+=1){ if(a[j]>a[i]&&dp[j]==maxx){ for(set<string>::iterator k=G[j].begin();k!=G[j].end();k++){ string s; s=(*k); char c[10]; sprintf(c, "%d", a[i]); string news(c); s+=news; G[i].insert(s); } } } res=max(res,dp[i]); } int countt=0; for(int i=0;i<n;i+=1) if(dp[i]==res){ int maxx=0; for(set<string>::iterator k=G[i].begin();k!=G[i].end();k++){ int len=(*k).length(); maxx=max(maxx,len); } for(set<string>::iterator k=G[i].begin();k!=G[i].end();k++){ if(k->length()==maxx){ string s=(*k); //cout<<s<<endl; countt+=1; } } } printf("%d %d\n",res,countt); } return 0; }
(2)
后来上网看了下他人的解法。
发现的确是高。其实并不需要记录每一条dp路径,而可以用一个path数组记录与dp相对应的法案数,
在dp过程中,将之前的,价格与当下相等的那个path值直接赋0(因为当前的path值一定大于等于之前的path),
这样之后不会重复加上方案数了。
自己在真正接受(原来只是看了一眼就自己敲了)这种想法之前还是自己敲了一个很难改的WA了的代码
详细错误在下面的代码注释里
#include <iostream> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <functional> #define maxn 5005 using namespace std; int a[maxn]; int dp[maxn]; int path[maxn]; int main() { int n; while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i+=1){ scanf("%d",&a[i]); dp[i]=1; path[i]=0; } int res=0; for(int i=0;i<n;i+=1){ int maxx=0; for(int j=0;j<i;j+=1){ if(a[j]>a[i]&&dp[j]+1>dp[i]){ dp[i]=dp[j]+1; maxx=max(maxx,dp[j]); } } set<int> s; for(int j=0;j<i;j+=1){ if(a[j]>a[i]&&dp[j]==maxx&&!s.count(a[j])){ //这里错了,可以看看这组数据 100 6 5 2 98 97 2 1 //当ai==1的时候,会先计算第一个2的path值,这个时候 //2就被压入了set,之后path值更大的2就不能再加入计算了 path[i]+=(path[j]==0?1:path[j]); s.insert(a[j]); } } s.clear(); res=max(res,dp[i]); } set<int> s; int countt=0; for(int i=0;i<n;i+=1) if(dp[i]==res&&s.count(a[i])==0){ s.insert(a[i]); countt+=path[i]; } printf("%d %d\n",res,countt); } return 0; }
下面是ac代码
#include <iostream> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <numeric> #include <functional> #define maxn 5005 using namespace std; int a[maxn]; int dp[maxn]; int path[maxn]; int main() { int n; while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i+=1){ scanf("%d",&a[i]); dp[i]=1; path[i]=1; } int res=0; for(int i=0;i<n;i+=1){ for(int j=0;j<i;j+=1){ if(a[i]<a[j]){ if(dp[j]+1>dp[i]){ dp[i]=dp[j]+1; path[i]=path[j]; } else if(dp[j]+1==dp[i]){ path[i]+=path[j]; } } else if(a[i]==a[j]){ path[j]=0; } } res=max(res,dp[i]); } int countt=0; for(int i=0;i<n;i+=1){ if(dp[i]==res){ countt+=path[i]; } } printf("%d %d\n",res,countt); } return 0; }
相关文章推荐
- poj 1952 BUY LOW, BUY LOWER 最长下降子序列+统计不重复方案数
- POJ1952(最长下降子序列+去重)
- POJ 1952(最长不下降子序列的个数)
- POJ-1887 Testing the CATCHER(dp,最长下降子序列)
- POJ-1952 最长下降子序列 + 方案数
- POJ 1887-Testing the CATCHER(dp_最长下降子序列)
- poj 1836 Alignment -dp(合唱队形变式)-最长上升子序列+最长下降子序列
- POJ 1952-最长下降子序列+去重
- poj 1952 BUY LOW, BUY LOWER 最长下降子序列计数
- POJ 1952 LITTLE SHOP OF FLOWERS(DP动归,最长递减子序列)
- POJ-1887 Testing the CATCHER(dp,最长下降子序列)
- poj 1952 BUY LOW, BUY LOWER(求最长下降子序列个数)
- POJ--1887:Testing the CATCHER (DP求最长非递增子序列)
- DP LIS(最长上升子序列) POJ 2533 POJ 1836 POJ 2138 HDU 1069
- poj2533--Longest Ordered Subsequence(dp:最长上升子序列)
- ACM 79. 渡轮问题(最长不下降子序列dp)
- DP 水题 最长不下降子序列
- [DP]TYVJ P1049 最长不下降子序列
- HDU1160 FatMouse's Speed(DP,最长下降子序列)
- 简单的dp@POJ(3)2533 最长上升子序列