• [noi707]LP


    (以下用$Sa=sum_{j=1}^{i}xicdot ai$,Sb和Sc同理)
    令f[i][x]表示前i个数,$Sale xle Sb$时最小的Sc
    考虑第i个数是否选择,可以得到递推式$f[i][x]=min(f[i-1][x],min(f[i-1][x-j])+ci)$(j满足$aile jle bi$),这个东西用单调队列维护即可
    (这个转移的正确性可以用充分和必要两方面来考虑,具体不证了)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1005
     4 #define oo 0x3f3f3f3f
     5 int t,n,m,l,r,a[N],b[N],c[N],q[N*10],f[N][N*10];
     6 int main(){
     7     scanf("%d",&t);
     8     while (t--){
     9         scanf("%d%d",&n,&m);
    10         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    11         for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    12         for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    13         for(int i=1;i<=m;i++)f[0][i]=oo;
    14         f[0][0]=0;
    15         for(int i=1;i<=n;i++){
    16             l=1;
    17             r=0;
    18             for(int j=0;j<=m;j++){
    19                 if (a[i]<=j){
    20                     while ((l<=r)&&(f[i-1][j]<=f[i-1][q[r]]))r--;
    21                     q[++r]=j-a[i];
    22                 }
    23                 while ((l<=r)&&(q[l]<j-b[i]))l++;
    24                 f[i][j]=f[i-1][j];
    25                 if (l<=r)f[i][j]=min(f[i][j],f[i-1][q[l]]+c[i]);
    26             }
    27         }
    28         if (f[n][m]==oo)printf("IMPOSSIBLE!!!
    ");
    29         else printf("%d
    ",f[n][m]);
    30     }
    31 }
    View Code
  • 相关阅读:
    高精度模板(未完待续)
    $CH0201$ 费解的开关
    $POJ2288$ $Islands$ $and$ $Bridges$
    luoguP1445 [Violet]樱花
    P3694 邦邦的大合唱站队
    [NOI2009]管道取珠
    [AHOI2006]基因匹配
    luogu P3411 序列变换
    HNOI2001 产品加工
    牛客ACM赛 B [小a的旅行计划 ]
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11619718.html
Copyright © 2020-2023  润新知