# P1108 low price purchase (DP)

Keywords: C++

## subject

P1108 low price purchase

## analysis

I'm exhausted physically and mentally. I'm almost autistic.
When I was sent N, I finally understood the meaning of this sentence

When two schemes "look the same" (that is, they form the same price queue), the two schemes are considered the same.

There are two questions about this question. The first question is obviously the longest strict descending subsequence. First, look at the data range: 5000. Just like the longest strict ascending subsequence, \ (n^2 \) can be written directly.

The second question is to find the number of schemes, which is also done with dp
Transfer equation

```//j<i
if (f[i] == f[j] + 1 && a[j] > a[i]) cnt[i] += cnt[j];```

Notice the same thing here,
If for two positions \ (I, J (J < I) \),
I f \ (f [i] = = f [j] \ & \ & A [i] = = a [j] \), it means that the two longest descending subsequences to \ (I \) and to \ (j \) are the same, which is a case (obviously should be).
And because we have calculated part of contribution once before, and we will not calculate it again, then we will not use it directly, so

`if (f[i] == f[j] && a[i] == a[j]) cnt[i] = 0;`

## Code

```#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, ans, sum;
int a[N], b[N], f[N], cnt[N];

template<class T>inline void read(T &x) {
x = 0; int f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
x = f ? -x : x;
return;
}

int main() {
for (int i = 1; i <= n; ++i) read(a[i]), b[i] = a[i];
sort(b + 1, b + 1 + n);
int len = unique(b + 1, b + 1 + n) - b - 1;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
for (int i = 1; i <= n; ++i) {
f[i] = 1;
for (int j = 1; j <= i; ++j)
if (a[j] > a[i]) f[i] = max(f[i], f[j] + 1);
}
for (int i = 1; i <= n; ++i) ans = max(f[i], ans);
for (int i = 1; i <= n; ++i) {
if (f[i] == 1) cnt[i] = 1;
for (int j = 1; j < i; ++j) {
if (f[i] == f[j] + 1 && a[j] > a[i]) cnt[i] += cnt[j];
if (f[i] == f[j] && a[i] == a[j]) cnt[i] = 0;
}
if (f[i] == ans) sum += cnt[i];
}
printf("%d %d", ans, sum);
return 0;
}```

Posted by suprsnipes on Tue, 05 Nov 2019 06:55:39 -0800