BZOJ 1049 [HAOI2006]数字序列 DP

第一问:最长xx子序列

第二问:f[i]表示前i个的最少花费,可以从满足条件j(假设以a[i]结尾的最长xx组序列长度为len,则j需要满足以a[j]结尾的最长xx组序列长度为len-1)

方法:记录最长xx子序列的转移,邻接表存,然后枚举每个转移。

ps:有个结论:如果从j转移到i的话,那么中间一定有一个k(k>=j&&k<i),使得j~k的高度都是a[j],k+1~i的高度都是i,且这样的花费是最优的,很容易想明白的~

 

这个暴力显然tle,怎么可能会ac?

数据弱,不解释

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <algorithm>
 6 
 7 #define N 55555
 8 #define INF 1LL<<60
 9 
10 using namespace std;
11 
12 int a[N],c[N];
13 int n,cnt,len;
14 int dp[N];
15 int head[N],next[N],to[N];
16 long long f[N],sum1[N],sum2[N];
17 
18 inline void add(int u,int v)
19 {
20     to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;
21 }
22 
23 inline void read()
24 {
25     scanf("%d",&n);
26     for(int i=1;i<=n;i++)
27     {
28         scanf("%d",&a[i]);
29         a[i]-=i;
30     }
31 }
32 
33 inline void step1()
34 {
35     n++;
36     a[n]=0x3f3f3f3f; a[0]=-a[n];
37     for(int i=0;i<=n;i++) c[i]=0x3f3f3f3f;
38     len=1; c[1]=a[1]; c[0]=-c[0];
39     dp[0]=0; dp[1]=1;
40     for(int i=2;i<=n;i++)
41     {
42         int x=upper_bound(c,c+1+len,a[i])-c;
43         len=max(len,x);
44         c[x]=min(c[x],a[i]);
45         dp[i]=x;
46     }
47     cout<<n-dp[n]<<endl;
48 }
49 
50 inline void step2()
51 {
52     memset(head,-1,sizeof head); cnt=0;
53     for(int i=n;i>=0;i--) add(dp[i],i),f[i]=INF;
54     f[0]=0;
55     for(int i=1,tmp;i<=n;i++)
56         for(int j=head[dp[i]-1];~j;j=next[j])
57         {
58             if(to[j]>i) break;
59             if(a[to[j]]>a[i]) continue;
60             for(int k=to[j];k<=i;k++) sum1[k]=abs(a[k]-a[to[j]]),sum2[k]=abs(a[k]-a[i]);
61             for(int k=to[j]+1;k<=i;k++) sum1[k]+=sum1[k-1],sum2[k]+=sum2[k-1];
62             for(int k=to[j];k<i;k++)
63                 f[i]=min(f[i],f[to[j]]+sum1[k]-sum1[to[j]]+sum2[i]-sum2[k]);
64         }
65     cout<<f[n]<<endl;
66 }
67 
68 inline void go()
69 {
70     step1();
71     step2();
72 }
73 
74 int main()
75 {
76     read(),go();
77     return 0;
78 }

 

 

posted @ 2013-03-12 23:46  proverbs  阅读(1714)  评论(0编辑  收藏  举报