• HDU 4381 Grid


    背包变形。

    将操作分为了两类,可以分开处理。

    可以dp处理出L[i]:L[i]=-1代表从左到右 i 长度不能被拼凑出来,L[i]!=-1表示从左到右 i 长度能被拼凑出,并且最小费用为L[i]。

    反着来一次dp就可以处理出R[i]:R[i]=-1代表从右到左 n+1-i 长度不能被拼凑出来,R[i]!=-1表示从右到左 n+1-i 长度能被拼凑出,并且最小费用为R[i]。

    由L[1---i] 与R[i+1---n]可以得出,以i为分割的最优解,于是,枚举 i 即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    inline int read()
    {
        char c = getchar();  while(!isdigit(c)) c = getchar();
        int x = 0;
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
        return x;
    }
    
    const int maxn=1000+10;
    int T,n,m;
    struct X { int op,a,x; }s[maxn];
    bool cmp1(X a,const X b) { return a.a<b.a; }
    bool cmp2(X a,const X b) { return a.a>b.a; }
    int L[maxn],R[maxn];
    
    int main()
    {
        scanf("%d",&T); int cas=1; while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].op,&s[i].a,&s[i].x);
            sort(s+1,s+1+m,cmp1);
    
            memset(L,-1,sizeof L); L[0]=0;
            for(int i=1;i<=m;i++)
            {
                if(s[i].op!=1) continue;
                for(int j=n;j>=0;j--)
                {
                    if(L[j]==-1) continue; if(j+s[i].x>s[i].a) continue;
                    if(L[j+s[i].x]==-1) L[j+s[i].x]=L[j]+1;
                    else L[j+s[i].x]=min(L[j+s[i].x],L[j]+1);
                }
            }
    
            memset(R,-1,sizeof R); R[n+1]=0;
            sort(s+1,s+1+m,cmp2);
            for(int i=1;i<=m;i++)
            {
                if(s[i].op!=2) continue;
                for(int j=1;j<=n+1;j++)
                {
                    if(R[j]==-1) continue; if(j-s[i].x<s[i].a) continue;
                    if(R[j-s[i].x]==-1) R[j-s[i].x]=R[j]+1;
                    else R[j-s[i].x]=min(R[j-s[i].x],R[j]+1);
                }
            }
            int ans1=0,ans2=0;
            for(int i=0;i<=n;i++)
            {
                int a1=0,a2=0,b1=0,b2=0;
                for(int j=i;j>=0;j--) { if(L[j]==-1) continue; a1=j,a2=L[j]; break; }
                for(int j=i+1;j<=n+1;j++) { if(R[j]==-1) continue; b1=n+1-j,b2=R[j]; break; }
                if(a1+b1>ans1) ans1=a1+b1, ans2=a2+b2;
                else if(a1+b1==ans1) ans2=min(ans2,a2+b2);
            }
            printf("Case %d: %d %d
    ",cas++,ans1,ans2);
        }
        return 0;
    }
  • 相关阅读:
    基于Servlet+smartUpload的文件上传
    基于Servlet+smartUpload的文件上传
    基于Servlet+smartUpload的文件上传
    dispatch_async 的 block 中是否该使用_weak self
    dispatch_async 的 block 中是否该使用_weak self
    dispatch_async 的 block 中是否该使用_weak self
    dispatch_async 的 block 中是否该使用_weak self
    Vagrant Tip: Virtualbox Guest Additions
    Vagrant Tip: Virtualbox Guest Additions
    Vagrant Tip: Virtualbox Guest Additions
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5747345.html
Copyright © 2020-2023  润新知