Poj--1952(DP,计数)
2014-12-11 21:35:26
思路:首先... 本题的数据比较水,按理说应该用高精度的... 不过long long 可过...
本来以为是个水dp,后来怎么搞都wa,再后来仔细看题意。。。原来不是按照数的不同位置来计数,而是数的值,比如5个数2 2 2 1 1,答案是2 1 (- -就一种)
所以如果按照正常的LDS转移后,对于dp[i],前面dp[j](1<=j<i)出现了几个相同值(即dp[j]==dp[i] , val[i] == val[j])那么只能保留最后的那个(为什么保留最后的呢,因为最后的计数最全,如果保留前面会导致丢失),所以扫一遍前面相同的dp,赋值为0。
1 /************************************************************************* 2 > File Name: 1952.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Thu 11 Dec 2014 06:00:11 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int N; 28 struct node{ 29 int v,dp; 30 ll num; 31 }t[5010]; 32 33 int main(){ 34 scanf("%d",&N); 35 for(int i = 1; i <= N; ++i){ 36 scanf("%d",&t[i].v); 37 } 38 int tmax = -1; 39 for(int i = 1; i <= N; ++i){ 40 t[i].dp = 1; 41 t[i].num = 1; 42 for(int j = 1; j < i; ++j) if(t[i].v < t[j].v){ 43 if(t[j].dp + 1 > t[i].dp){ 44 t[i].dp = t[j].dp + 1; 45 t[i].num = t[j].num; 46 } 47 else if(t[j].dp + 1 == t[i].dp){ 48 t[i].num += t[j].num; 49 } 50 } 51 for(int j = i - 1; j >= 1; --j){ 52 if(t[j].v == t[i].v && t[j].dp == t[i].dp){ 53 t[j].num = 0; 54 break; 55 } 56 } 57 tmax = max(tmax,t[i].dp); 58 } 59 ll ans = 0; 60 for(int i = 1; i <= N; ++i){ 61 if(t[i].dp == tmax){ 62 ans += t[i].num; 63 } 64 } 65 printf("%d %I64d\n",tmax,ans); 66 return 0; 67 }