dp优化

入口

A(fzu 1894)

  普通的单调队列,trick是进队判断的符号选取(>=wa , >ac).

B(poj 2823)

  没什么好说的 ,坑爹poj   g++,tle ;c++,ac.

C(hdu 3415)

  尝试封装了一下单调队列。。。感觉也没有方便多少.

 1 #define maxn 100010
 2 #define INF 1000000000
 3 int a[maxn<<1],p[maxn<<1],n,k;
 4 
 5 struct Que
 6 {
 7     int q[maxn<<1],front,tail,cmp;
 8     void clear()    {front = tail = 0;}
 9     void ins(int id)
10     {
11         while (front<tail && a[id]*cmp>a[q[tail-1]]*cmp)    tail--;
12         q[tail++] = id;
13     }
14     void keep(int range)
15     {
16         while (front<tail && q[tail-1]-q[front]>=range)    front++;
17     }
18     int query(int id)    {    return q[id];    }
19 };Que q;
20 void input()
21 {
22     int i;
23     scanf("%d%d",&n,&k);
24     for ( i=1 ; i<=n ; i++ )
25     {
26         scanf("%d",&a[i]);
27         a[i+n] = a[i];    p[i] = i;    p[i+n] = p[i];
28     }
29     for ( i=1 ; i<=2*n ; i++ ) a[i] = a[i-1]+a[i];
30 }
31 void solv()
32 {
33     int i,l,r,sum;
34     l = r = sum = -INF;
35     q.clear();
36     q.cmp = -1;
37     for ( i=0 ; i<2*n ; i++ )
38     {
39         q.ins(i);
40         q.keep(k);
41         if (a[i+1]-a[q.query(q.front)] > sum)
42         {
43             l = p[q.query(q.front)]+1;
44             r = p[i+1];
45             sum = a[i+1]-a[q.query(q.front)];
46         }else if (a[i+1]-a[q.query(q.front)] == sum)
47         {
48             if (p[q.query(q.front)]+1<l)
49             {
50                 l = p[q.query(q.front)]+1;
51                 r = p[i+1];
52             }else if (p[q.query(q.front)]+1==l && p[i+1]<r)    r=p[i+1];
53         }
54     }
55     printf("%d %d %d\n",sum,l,r);
56 }
57 int main()
58 {
59     int cas;
60     scanf("%d",&cas);
61     while (cas--)
62     {
63         input();
64         solv();
65     }
66     return 0;
67 }
View Code

D(hdu 3401)

  先列出朴素的dp方程逐渐,分析出可以优化的地方:

  递推优化:  dp[i][j] = max(dp[i][j],dp[i-1][j]);

  单调队列优化:  dp[i][j] = max{  dp[i][j]  ,  dp[i-w-1][q.head]+(j-q.head)*num  };

  trick是前w+1天不能进行买卖,要特判并跳过买卖的决策.

 1 #include <cmath>
 2 #include <ctime>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <algorithm>
 9 using namespace std;
10 #define maxn 2020
11 #define INF 1000000000
12 int ap[maxn],bp[maxn],as[maxn],bs[maxn],t,maxp,w,dp[maxn][maxn];
13 void input()
14 {
15     int i;
16     scanf("%d%d%d",&t,&maxp,&w);
17     for ( i=1 ; i<=t ; i++ )    scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
18 }
19 int q[maxn],front,tail;
20 void DP()
21 {
22     int i,j,k;
23     for ( i=1,dp[0][0]=0 ; i<=maxp ; i++ )    dp[0][i] = -INF;
24     for ( i=1 ; i<=t ; i++ )
25     for ( j=0 ; j<=maxp ; j++ )
26     {
27         if (j<=as[i])    dp[i][j] = -ap[i]*j;
28         else    dp[i][j] = -INF;
29     }
30     for ( i=1 ; i<=t ; i++ )
31     {
32         for ( j=0 ; j<=maxp ; j++ )    dp[i][j] = max(dp[i][j],dp[i-1][j]);
33         if ((k=i-w-1)<0)    continue;
34 
35         front = tail = 0;
36         //    buy
37         for ( j=0 ; j<=maxp ; j++ )
38         {
39             while (front<tail && j-q[front]>as[i])    front++;
40             while (front<tail && dp[k][j]+j*ap[i]>=dp[k][q[tail-1]]+q[tail-1]*ap[i])    tail--;
41             q[tail++] = j;
42             int tmp = dp[k][q[front]]-(j-q[front])*ap[i];
43         //    printf("dp[%d][%d] = max:    %d    ,    dp[%d][%d]-(%d-%d)*%d = %d\n",i,j,dp[i][j],k,q[front],j,q[front],ap[i],max(dp[i][j],tmp));
44             dp[i][j] = max(dp[i][j],tmp);
45         }
46 
47         front = tail = 0;
48         //    sell
49         for ( j=maxp ; j>=0 ; j-- )
50         {
51             while (front<tail && q[front]-j>bs[i])    front++;
52             while (front<tail && dp[k][j]+j*bp[i]>=dp[k][q[tail-1]]+q[tail-1]*bp[i])    tail--;
53             q[tail++] = j;
54             int tmp = dp[k][q[front]]-(j-q[front])*bp[i];
55         //    printf("dp[%d][%d] = max:    %d    ,    dp[%d][%d]-(%d-%d)*%d = %d\n",i,j,dp[i][j],k,q[front],j,q[front],bp[i],max(dp[i][j],tmp));
56             dp[i][j] = max(dp[i][j],tmp);
57         }
58     }
59     int ans=-INF;
60     for ( i=0 ; i<=t ; i++ )
61     for ( j=0 ; j<=maxp ; j++ )    ans = max(ans,dp[i][j]);
62     printf("%d\n",ans);
63 }
64 int main()
65 {
66     int cas;
67     scanf("%d",&cas);
68     while (cas--)
69     {
70         input();
71         DP();
72     }
73     return 0;
74 }
View Code

 

E(hdu 3530)

  关键是求区间给定区间的最大值和最小值,有很多办法,在此题中,可以用单调队列做到O(n).

  trick:  当最大-最小>k时需要删除队列元素维护,但是当小于m时不用进行删除操作,因为没用。。。

 1 #include <cmath>
 2 #include <ctime>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <algorithm>
 9 using namespace std;
10 #define maxn 1000100
11 int n,m,k,a[maxn];
12 int qs[maxn],ts,fs,ql[maxn],tl,fl,q[maxn],front,tail;
13 bool inq[maxn];
14 void input()
15 {
16     int i;
17     for ( i=1 ; i<=n ; i++ )    scanf("%d",&a[i]);
18 }
19 int queryl()
20 {
21     while (fl<tl && !inq[ql[fl]])    fl++;
22     return a[ql[fl]];
23 }
24 int querys()
25 {
26     while (fs<ts && !inq[qs[fs]])    fs++;
27     return a[qs[fs]];
28 }
29 void solv()
30 {
31     int i,ans=0;
32     front = tail = fs = ts = fl = tl = 0;
33     for ( i=1 ; i<=n ; i++ )
34     {
35         q[tail++] = i;
36         inq[i] = 1;
37         while (fs<ts && a[i]<a[qs[ts-1]])    ts--;
38         qs[ts++] = i;
39         while (fl<tl && a[i]>a[ql[tl-1]])    tl--;
40         ql[tl++] = i;
41         while(front<tail && queryl()-querys()>k)
42         {
43             inq[q[front]] = 0;
44             front++;
45         }
46         if (queryl()-querys()>=m && queryl()-querys()<=k)    ans = max(ans,q[tail-1]-q[front]+1);
47     }
48     printf("%d\n",ans);
49 }
50 int main()
51 {
52     while (scanf("%d%d%d",&n,&m,&k)!=EOF)
53     {
54         input();
55         solv();
56     }
57     return 0;
58 }
View Code

 

F(poj3017)

  非常有启发性的一题:利用线段树的单点更新更新单调队列里面的值.单调队列保证了快速获得区间最值,线段树的区间查询保证了答案的最优性.

 1 #include <cmath>
 2 #include <ctime>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <algorithm>
 9 using namespace std;
10 typedef long long llong;
11 const llong INF = 1ll<<60;
12 #define maxn 100100
13 #define ls (rt<<1)
14 #define rs (rt<<1|1)
15 #define mid ((l+r)>>1)
16 struct node
17 {
18     int l,r,big;
19 };node q[maxn];
20 llong tree[maxn<<2],m,dp[maxn];
21 int a[maxn],n,front,tail;
22 void buildtree(int l,int r,int rt)
23 {
24     tree[rt] = INF;
25     if (l == r)    return;
26     buildtree(l,mid,ls);
27     buildtree(mid+1,r,rs);
28 }
29 void pushup(int rt)
30 {
31     tree[rt] = min(tree[ls],tree[rs]);
32 }
33 void ins(llong var,int pos,int l,int r,int rt)
34 {
35     if (l == r)
36     {
37         tree[rt] = var;
38         return;
39     }
40     if (pos<=mid)    ins(var,pos,l,mid,ls);
41     else    ins(var,pos,mid+1,r,rs);
42     pushup(rt);
43 }
44 llong query(int L,int R,int l,int r,int rt)
45 {
46     llong res1,res2;
47     res1 = res2 = INF;
48     if (L<=l && r<=R)    return tree[rt];
49     if (L<=mid)    res1 = query(L,R,l,mid,ls);
50     if (R>mid)    res2 = query(L,R,mid+1,r,rs);
51     return min(res1,res2);
52 }
53 llong solv()
54 {
55     int i,lft;
56     llong cnt=0;
57     node tmp;
58     buildtree(0,n,1);
59     front = tail = 0;
60     for ( i=1 ; i<=n ; i++ )
61     if (a[i]>m)    return -1;
62     for ( lft=i=1,dp[0]=0 ; i<=n ; i++ )
63     {
64         cnt += a[i];
65         while (cnt>m)
66         {
67             q[front].l++;
68             if (q[front].l>q[front].r)
69             {
70                 ins(INF,front,0,n,1);
71                 front++;
72             }else    ins(dp[q[front].l-1]+q[front].big,front,0,n,1);
73             cnt -= a[lft++];
74         }
75         tmp.l = tmp.r = i;    tmp.big = a[i];
76         while (front<tail && tmp.big>=q[tail-1].big)
77         {
78             tmp.l = q[tail-1].l;    //merge
79             ins(INF,tail-1,0,n,1);
80             tail--;
81         }
82         q[tail++] = tmp;
83         ins(dp[q[tail-1].l-1]+q[tail-1].big,tail-1,0,n,1);
84         dp[i] = query(front,tail-1,0,n,1);
85     //    printf("dp[%d]=%I64d\n",i,dp[i]);
86     }
87     return dp[n];
88 }
89 int main()
90 {
91     while (scanf("%d%I64d",&n,&m)!=EOF)
92     {
93         for (int i=1 ; i<=n ; i++ ) scanf("%d",&a[i]);
94         printf("%I64d\n",solv());
95     }
96     return 0;
97 }
View Code

G(poj3245)

  为了满足 " 当p<q 时 , Bp > Aq " 的条件,需要先将数据预处理成块状, 即 对所有p ,要找到最大的q 使得 B<= Aq  .

  这是第一步,朴素做法O(n^2) ,  用一点技巧可以做到nlogn :  线段树(比较麻烦,可能要离散化,代码量大) 或者 分别对A和对B降序排序O(nlogn) ,再用2个指针扫描 O(n) , 要记得记录排序前的原始下标.

  第二步,在limt的限制下求最小sum的分组方法, 很容易想到要二分答案.

    第三步,对于二分的sum值,需要一个验证办法.注意,让每组尽量接近sum的贪心分组办法是错的, 因为这里还要考虑到 ΣMi 的限制.

  老老实实dp:

  dp[i]表示以第i个为结尾, ΣM 最小的分组方法.

  dp[i] = min {dp[j] + max{aj+1,...,ai} }.

  这个方程和F题的非常相似,把决策存在单调队列里,用线段树得到最优值.

  1 #include <cmath>
  2 #include <ctime>
  3 #include <queue>
  4 #include <cstdio>
  5 #include <string>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <algorithm>
  9 using namespace std;
 10 typedef long long llong;
 11 #define maxn 50100
 12 #define ls (rt<<1)
 13 #define rs ((rt<<1)+1)
 14 #define mid ((l+r)>>1)
 15 #define BIG 1
 16 #define SML 0
 17 #define INF (1ll<<31)
 18 struct node
 19 {
 20     int a,b,id;
 21 };node p[maxn],sa[maxn],sb[maxn],e[maxn];
 22 llong init[2];
 23 llong sumb[maxn],tree[maxn<<2];
 24 int n,lmt,cnte,lst[maxn];
 25 
 26 bool cmpa(const node& u,const node& v)    { return u.a>v.a; }
 27 bool cmpb(const node& u,const node& v)    { return u.b>v.b; }
 28 llong query_big(int L,int R,int l,int r,int rt)
 29 {
 30     llong resl,resr;
 31     resl = resr = init[BIG];
 32     if (L<=l && r<=R)    return tree[rt];
 33     if (L<=mid)    resl = query_big(L,R,l,mid,ls);
 34     if (R>mid)    resr = query_big(L,R,mid+1,r,rs);
 35     return max(resl,resr);
 36 }
 37 llong query_sml(int L,int R,int l,int r,int rt)
 38 {
 39     llong resl,resr;
 40     resl = resr = init[SML];
 41     if (L<=l && r<=R)    return tree[rt];
 42     if (L<=mid)    resl = query_sml(L,R,l,mid,ls);
 43     if (R>mid)    resr = query_sml(L,R,mid+1,r,rs);
 44     return min(resl,resr);
 45 }
 46 void buildtree(int l,int r,int rt,int flg)
 47 {
 48     tree[rt] = init[flg];
 49     if (l==r)    return;
 50     buildtree(l,mid,ls,flg);
 51     buildtree(mid+1,r,rs,flg);
 52 }
 53 void pushup(int rt,int flg)
 54 {
 55     if (flg==BIG)    tree[rt] = max(tree[ls],tree[rs]);
 56     else    tree[rt] = min(tree[rs],tree[ls]);
 57 }
 58 void ins(int val,int pos,int l,int r,int rt,int flg)
 59 {
 60     if (l==r)    { tree[rt]=val; return; }
 61     if (pos<=mid)    ins(val,pos,l,mid,ls,flg);
 62     else    ins(val,pos,mid+1,r,rs,flg);
 63     pushup(rt,flg);
 64 }
 65 void pretreat()
 66 {
 67     int i,j,k;
 68     buildtree(1,n,1,BIG);
 69     for ( i=1 ;i<=n ; i++ )    sa[i]=p[i],    sb[i]=p[i];
 70     sort(sa+1,sa+1+n,cmpa);    sort(sb+1,sb+1+n,cmpb);
 71 //    for ( i=1 ; i<=n ; i++ ) printf("sa: a=%d id=%d\nsb: b=%d id=%d\n\n",sa[i].a,sa[i].id,sb[i].b,sb[i].id);
 72     for ( i=j=1,k=0 ; i<=n ; i++ )
 73     {
 74         lst[ sb[i].id ] = sb[i].id;
 75         while (j<=n && sa[j].a>=sb[i].b) k=max(k,sa[j].id),j++;
 76         lst[ sb[i].id ] = max(sb[i].id,k);
 77         ins(lst[ sb[i].id ],sb[i].id,1,n,1,BIG);
 78     }
 79     for ( i=1 ; i<=n ; i++ )
 80         lst[i] = query_big(i,lst[i],1,n,1);
 81     buildtree(1,n,1,BIG);
 82     for ( i=1 ; i<=n ; i++ ) sumb[i] = sumb[i-1] + p[i].b;
 83     for ( i=1 ; i<=n ; i++ )    ins(p[i].a,i,1,n,1,BIG);
 84     for ( i=1,cnte=0 ; i<=n ; i++ )
 85     {
 86         e[++cnte].a = query_big(i,lst[i],1,n,1);
 87         e[cnte].b = sumb[lst[i]] - sumb[i-1];
 88         e[cnte].id = cnte;
 89         i = lst[i];
 90     }
 91 //    for ( i=1 ; i<=cnte ; i++ ) printf("e[%d]: a=%d b=%d\n",i,e[i].a,e[i].b);
 92     for ( i=1 ; i<=cnte ; i++ )    sumb[i] = sumb[i-1] + e[i].b;
 93 }
 94 struct node2
 95 {
 96     int l,r,big;
 97 };node2 q[maxn];
 98 
 99 int front,tail;
100 llong dp[maxn];
101 int check(int sum)
102 {
103     int i,lft;
104     llong cnt=0;
105     node2 tmp;
106 
107     front = tail = 0;
108     for ( i=1 ; i<=cnte ; i++ ) if (e[i].b>sum)    return 0;
109 
110     for ( i=lft=1 ; i<=cnte ; i++ )
111     {
112         cnt += e[i].b;
113         while (cnt>sum)
114         {
115             q[front].l++;
116             if (q[front].l>q[front].r)
117             {
118                 ins(init[SML],front,0,n,1,SML);
119                 front++;
120             }else    ins(dp[q[front].l-1]+q[front].big,front,0,n,1,SML);
121             cnt -= e[lft++].b;
122         }
123         tmp.l = tmp.r = i;    tmp.big = e[i].a;
124         while (front<tail && tmp.big>=q[tail-1].big)
125         {
126             tmp.l = q[tail-1].l;
127             ins(init[SML],tail-1,0,n,1,SML);
128             tail--;
129         }
130         q[tail++] = tmp;
131         ins(dp[tmp.l-1]+tmp.big,tail-1,0,n,1,SML);
132         dp[i] = query_sml(front,tail-1,0,n,1);
133     }
134     if (dp[cnte]<=lmt)    return 1;
135     else    return 0;
136 }
137 int solv()
138 {
139     int l,r;
140     l = 0;    r = sumb[n];
141     while (l<r)
142     {
143         if (check(mid))    r=mid;
144         else    l=mid+1;
145     }    return r;
146 }
147 int main()
148 {
149     init[BIG] = 0;    init[SML] = INF;
150     scanf("%d%d",&n,&lmt);
151     for (int i=1 ; i<=n ; i++ ) {    scanf("%d%d",&p[i].a,&p[i].b);    p[i].id=i;    }
152     pretreat();
153     int ans = solv();
154     printf("%d\n",ans);
155     return 0;
156 }
View Code

斜率优化dp:

H(hdu 2993)

 1 #include <cmath>
 2 #include <ctime>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <algorithm>
 9 using namespace std;
10 typedef long long llong;
11 #define maxn 100100
12 #define ls (rt<<1)
13 #define rs ((rt<<1)+1)
14 #define mid ((l+r)<<1)
15 int sum[maxn];
16 int n,m;
17 int q[maxn],front,tail;
18 
19 double g(int a,int b)
20 {
21     double res = (double)(sum[b]-sum[a-1])/(double)(b-a+1.0);
22     return res;
23 }
24 void solv()
25 {
26     int i;
27     double ans=0;
28     front = tail = 0;
29     for ( i=m ; i<=n ; i++ )
30     {
31         while (front+1<tail && g(q[tail-2],q[tail-1])>g(q[tail-1],i-m+1))    tail--;
32         q[tail++] = i-m+1;
33         while (front+1<tail && g(q[front],i)<=g(q[front+1],i)) front++;
34         ans = max(ans,g(q[front],i));
35     }
36     printf("%.2lf\n",ans);
37 }
38 int GetInt()
39 {
40     char ch=getchar();
41     while(ch<'0'||ch>'9')ch=getchar();
42     int num=0;
43     while(ch>='0'&&ch<='9'){
44         num=num*10+ch-'0';
45         ch=getchar();
46     }
47     return num;
48 }
49 int main()
50 {
51     while (scanf("%d%d",&n,&m)!=EOF)
52     {
53         for (int i=1 ; i<=n ; i++ )
54         {
55             sum[i] = GetInt();
56             sum[i] += sum[i-1];
57         }
58         solv();
59     }
60     return 0;
61 }
View Code

I(hdu 2829)

 1 #include <cmath>
 2 #include <ctime>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <string>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <algorithm>
 9 using namespace std;
10 #define maxn 1010
11 typedef long long llong;
12 #define ls (rt<<1)
13 #define rs ((rt<<1)+1)
14 #define mid ((l+r)<<1)
15 const llong INF = 1ll<<62;
16 llong dp[maxn][maxn],v[maxn],sum[maxn];
17 int n,m,a[maxn];
18 
19 void init()
20 {
21     int i;
22     for ( i=1 ; i<=n ; i++ ) sum[i] = sum[i-1]+a[i];
23     for ( i=1 ; i<=n ; i++ ) v[i] = v[i-1]+sum[i-1]*a[i];
24 }
25 int q[maxn],front,tail;
26 
27 llong w(int j,int i)
28 {
29     return v[i]-v[j]-sum[j]*(sum[i]-sum[j]);
30 }
31 int x;
32 double g(int id,int a,int b)
33 {
34     double xa,xb,ya,yb;
35     ya = dp[id][a] - v[a]+sum[a]*sum[a];    xa = sum[a];
36     yb = dp[id][b] - v[b]+sum[b]*sum[b];    xb = sum[b];
37     return (ya-yb) / (xa-xb);
38 }
39 void DP()
40 {
41     int i,j;
42     for ( i=0 ; i<=n ; i++ ) dp[0][i] = v[i];
43 //    for ( i=0 ; i<=n ; i++ ) printf("dp[0][%d]=%I64d\n",i,dp[0][i]);    printf("\n");
44 
45     for ( i=1 ; i<=m ; i++ )
46     {
47         front = tail = 0;
48         q[tail++] = i;
49         for ( j=i+1 ; j<=n ; j++ )
50         {
51             x = j;
52             while (front+1<tail && g(i-1,q[front],q[front+1])<=(double)sum[j])    front++;
53             dp[i][j] = dp[i-1][q[front]] + w(q[front],j);
54     //        printf("dp[%d][%d] = %I64d        q[front]=%d\n",i,j,dp[i][j],q[front]);
55             while (front+1<tail && g(i-1,q[tail-2],q[tail-1])>=g(i-1,q[tail-1],j))    tail--;
56             q[tail++] = j;
57         }
58     }
59     llong res=INF;
60     for ( i=0 ; i<=m ; i++ )    res = min(res,dp[i][n]);
61     cout<<res<<endl;
62 }
63 int main()
64 {
65     while (scanf("%d%d",&n,&m)!=EOF)
66     {
67         if (!n && !m)    break;
68         for (int i=1 ; i<=n ; i++ ) scanf("%d",&a[i]);
69         init();
70         DP();
71     }
72     return 0;
73 }
View Code

J(hdu 3507)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <queue>
 6 #include <vector>
 7 using namespace std;
 8 typedef long long llong;
 9 #define maxn 600010
10 llong dp[maxn],sum[maxn];
11 int a[maxn],n,m,q[maxn],front,tail;
12 
13 double dx(int a,int b){return (double)(sum[a]-sum[b]);}
14 double dy(int a,int b){return (double)(dp[a]+sum[a]*sum[a]-dp[b]-sum[b]*sum[b]);}
15 int check(int a,int b,llong c)
16 {
17     llong resa = dp[a] + (sum[a]-c)*(sum[a]-c);
18     llong resb = dp[b] + (sum[b]-c)*(sum[b]-c);
19     if (resa>resb)    return 1;
20     else    return 0;
21 }
22 void solv()
23 {
24     int i;
25     for ( i=1 ; i<=n ; i++ ) sum[i] = sum[i-1] + a[i];
26     front = tail = 0;
27     q[tail++] = 0;
28     for ( i=1 ; i<=n ; i++ )
29     {
30         while (front+1<tail && check(q[front],q[front+1],sum[i])) front++;
31         dp[i] = dp[q[front]] + (sum[i]-sum[q[front]]) * (sum[i]-sum[q[front]])+m;
32    //     printf("dp[%d] = %lld\n",i,dp[i]);
33         while (front+1<tail && dy(q[tail-1],q[tail-2]) * dx(i,q[tail-1]) >= dx(q[tail-1],q[tail-2]) * dy(i,q[tail-1])) tail--;
34         q[tail++] = i;
35     }
36     cout<<dp[n]<<endl;
37 }
38 int main()
39 {
40     while (scanf("%d%d",&n,&m)!=EOF)
41     {
42         for (int i=1 ; i<=n ; i++ ) scanf("%d",&a[i]);
43         solv();
44     }
45     return 0;
46 }
View Code

  I,J需要比较决策得到斜率形式,比较决策的形式:

    i<j<k 时  g(i,j)<常数c可推出j更优 ,g(i,j)<g(j,k)<常数c 可推出决策j不会为最优可从集合中去掉

  H不需要比较决策直接是斜率形式.

   设i<j<k , g(i,j)>g(j,k) 可以通过图像知道上凸点j不会成为最优决策.

转载于:https://www.cnblogs.com/eggeek/p/3175084.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值