低价购买 洛谷1108 codevs4748 dp
首先,,我相信第一问是可以做出来的,,,做不出来自行面壁思过,,,
第二问,我们可以发现,如果f[i]为1时应该将其g[i]初始化为1,当初就是因为这个wa了一个世纪,之后先考虑不需要判重时的情况,如果对于j < i可知如果f[i] == f[j] + 1 && a[j] > a[i] 那么存在由i到j的方案,即g[i] += g[j],然后考虑判重,在处理第i位时,for j (1) -> (i-1) 判断如果满足上述条件,更新g[i],如果存在f[i] == f[j] && a[i] == a[j],则一定出现重复,直接将g[j]清零以避免之后重复运算
Warning:注意初始化,,,luogu上一页的wa看得我那叫一个心酸,,
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int maxn = 5000 + 500; 6 7 long long f[maxn], g[maxn]; 8 long long n; 9 long long a[maxn]; 10 11 12 int main () { 13 scanf("%lld", &n); 14 for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); 15 for (int i = 1; i <= n; i++) { 16 f[i] = 1; 17 } 18 19 for (int i = 1; i <= n; i++) { 20 for (int j = 1; j < i; j++) 21 if (a[j] > a[i]) f[i] = std :: max(f[i], f[j] + 1); 22 for (int j = 1; j < i; j++) { 23 if (a[j] > a[i] && f[i] == f[j] + 1) g[i] += g[j]; 24 else if (a[i] == a[j] && f[i] == f[j]) g[j] = 0; 25 } 26 if (f[i] == 1) g[i] = 1; 27 } 28 29 long long ans = 0; 30 long long tans = 0; 31 for (int i = 1; i <= n; i++) { 32 if (f[i] > ans) { 33 ans = f[i]; 34 tans = g[i]; 35 } else if (f[i] == ans) { 36 tans += g[i]; 37 } 38 } 39 // --------------- 40 //for (int i = 1; i <= n; i++) 41 // printf("f[%d] = %d\ng[%d] = %d\n", i, f[i], i, g[i]); 42 // -------------- 43 printf("%lld %lld", ans, tans); 44 45 return 0; 46 }