[USACO4.3.1]Buy Low, Buy Lower

来源:互联网 发布:单片机编程入门教程 编辑:程序博客网 时间:2024/06/05 09:46

新博客参见emoairx.github.io
Buy Low, Buy Lower

The advice to "buy low" is half the formula to success in the stock market. But to be considered a great investor you must also follow this problems' advice:

"Buy low, buy lower"

That is, each time you buy a stock, you must purchase more 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 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 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.

By way of example, suppose on successive days stock is selling like this:

 Day   1  2  3  4  5  6  7  8  9 10 11 12Price 68 69 54 64 68 64 70 67 78 62 98 87

In the example above, the best investor (by this problem, anyway) can buy at most four times if they purchase at a lower price each time. One four day sequence (there might be others) of acceptable buys is:

Day    2  5  6 10Price 69 68 64 62

PROGRAM NAME: buylow

INPUT FORMAT

Line 1:N (1 <= N <= 5000), the number of days for which stock prices are available.Line 2..etc:A series of N positive space-separated integers (which may require more than one line of data) that tell the price for that day. The integers will fit into 32 bits quite nicely.

SAMPLE INPUT (file buylow.in)

1268 69 54 64 68 64 70 6778 62 98 87

OUTPUT FORMAT

Two integers on a single line:

  • the length of the longest sequence of decreasing prices
  • the number of sequences that have this length

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 OUTPUT (file buylow.out)

4 2
给你n个数,问你最长上升子序列的长度
以及:
本质不同的(至少一个不同)的最长的序列的个数。
第一问其实很好做的。(N^2就可以了)
最难处理的应该是第二问,主要是因为有不同的限制其实可以保存它由哪些不同的转移过来累加即可
其中已经可能转移的就不累加了
要打个标记。因为数据有点大
所以先离散化。
然后打上标记。
第一次因为没有注意到要高精度,后来注意到了。下面是我的高精度(部分模板)
没有高精度/高精度,gcd,压位等高难度动作
struct GJD{int val[400],len;bool operator < (const GJD &x) const{if (len < x.len) return true;if (len > x.len) return false;for (int i=len;i>=1;i--){if (val[i] < x.val[i]) return true;if (val[i] > x.val[i]) return false;}return false;//等于 }GJD operator + (const GJD &x) const{GJD c;memset(c.val,0,sizeof(c.val));if (len < x.len) c.len = x.len; else c.len = len;for (int i=1;i<=c.len;i++){c.val[i] += val[i] + x.val[i];c.val[i+1] += c.val[i] / 10;c.val[i] %= 10;}while (c.val[c.len+1] > 0){c.len++;c.val[c.len+1] += c.val[c.len] / 10;c.val[c.len] %= 10;}return c;}GJD operator * (const int &x) const{GJD c;memset(c.val,0,sizeof(c.val));c.len = len;for (int i=1;i<=c.len;i++){c.val[i] = val[i] * x;}for (int i=1;i<=c.len;i++){c.val[i+1] += c.val[i] / 10;c.val[i] %= 10;}while (c.val[c.len+1] > 0){c.len++;c.val[c.len+1] += c.val[c.len] / 10;c.val[c.len] %= 10;}return c;}GJD operator * (const GJD &x) const{GJD c;memset(c.val,0,sizeof(c.val));for (int i=1;i<=len;i++){for (int j=1;j<=x.len;j++){c.val[i+j-1] += val[i] * x.val[j];}}c.len = len + x.len - 1;for (int i=1;i<=c.len;i++){c.val[i+1] += c.val[i] / 10;c.val[i] %= 10;}while (c.val[c.len+1] > 0){c.len++;c.val[c.len+1] += c.val[c.len] / 10;c.val[c.len] %= 10;}return c;}GJD operator / (const int &x) const{GJD a;a.len = len;for (int i=1;i<=len;i++) a.val[i] = val[i];GJD c;memset(c.val,0,sizeof(c.val));c.len = a.len;for (int i=c.len;i>=1;i--){c.val[i] = a.val[i] / x;a.val[i-1] += (a.val[i] % x) * 10;}while (c.val[c.len] == 0) c.len--;return c;}void clear(int x){if (x == 0){len = 1;memset(val,0,sizeof(val));return ;}len = 0;while (x){val[++len] = x % 10;x /= 10;}}void write(){//printf("%d\n",len);printf("%d",val[len]);for (int i=len-1;i>=1;i--){//if (val[i] < 100) …… printf("%d",val[i]);}}}



/*ID:cqz15311LANG:C++PROG:buylow */ #include<cstdio>#include<cmath>#include<algorithm>#include<iostream>#include<cstring>using namespace std;typedef long long LL;const int maxn = 5333;
从上面抄下来……
…………
……
GJD num[maxn];int a[maxn],dp[maxn],n;bool used[maxn];struct Y{int val,id;bool operator < (const Y &x) const{return val < x.val;}}y[maxn];int main(){freopen("buylow.in","r",stdin);freopen("buylow.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&a[i]);y[i] . val = a[i];y[i] . id = i;}sort(y+1,y+1+n);int cnt = 0;for (int i=1;i<=n;i++){if (i == 1 || y[i] . val != y[i-1] . val){a[y[i] . id] = ++cnt;} elsea[y[i] . id] = cnt;}a[0] = n+1;a[++n] = -1;num[0] .clear(1);dp[0] = 0;memset(used,false,sizeof(used));for (int i=1;i<=n;i++){dp[i] = 1;for (int j=i-1;j>=0;j--){if (a[i] < a[j]){if (dp[j] + 1 > dp[i])dp[i] = dp[j] + 1;}}for (int j=i-1;j>=0;j--){if ((a[j] > a[i]) && (dp[i] == (dp[j]+1))){if (!used[a[j]]){num[i] = num[i] + num[j];used[a[j]] = true;}}}for (int j=i-1;j>=0;j--) used[a[j]] = false;}printf("%d ",dp[n]-1);num[n] . write();puts("");fclose(stdin);fclose(stdout);return 0;}/*Executing...   Test 1: TEST OK [0.000 secs, 12620 KB]   Test 2: TEST OK [0.000 secs, 12620 KB]   Test 3: TEST OK [0.000 secs, 12620 KB]   Test 4: TEST OK [0.000 secs, 12620 KB]   Test 5: TEST OK [0.000 secs, 12620 KB]   Test 6: TEST OK [0.014 secs, 12620 KB]   Test 7: TEST OK [0.000 secs, 12620 KB]   Test 8: TEST OK [0.000 secs, 12620 KB]   Test 9: TEST OK [0.042 secs, 12620 KB]   Test 10: TEST OK [0.308 secs, 12620 KB]All tests OK.Your program ('buylow') produced all correct answers!  This is yoursubmission #2 for this problem.  Congratulations!*/ 


原创粉丝点击