hdu 4381 Grid(背包 + 思维)


Problem Description
  There are n boxes in one line numbered 1 to n, at the beginning, all boxes are black. Two kinds of operations are provided to you:

1 a i x i :You can choose any x i black boxes in interval [1,a i], and color them white;
2 a i x i :You can choose any x i black boxes in interval [a i,n], and color them white;

  lcq wants to know if she use these operations in optimal strategy, the maximum number of white boxes she can get, and if she get maximum white boxes, the minimum number of operations she should use.
Tips: 
1. It is obvious that sometimes you can choose not to use some operations.
2. If the interval of one operation didn’t have enough black boxes, you can’t use this operation.
 

Input
  The first line contains one integer T, indicating the number of test case.
  The first line of each test case contains two integers N (1 <= N <= 1000) and M (1<=M<=1000), indicating that there are N grids and M operations in total. Then M lines followed, each of which contains three integers s i(1<=s i<=2) , a i and x i (0 <= x i <= N,1<=a i<=N), si indicating the type of this operation, a i and x i indicating that the interval is [1,a i] or [a i,n](depending on s i), and you can choose x i black boxes and color them white.
 

Output
  For each test case, output case number first. Then output two integers, the first one is the maximum boxes she can get, the second one is the minimum operations she should use.
 

Sample Input
  
  
1 5 2 2 3 3 1 3 3
 

Sample Output
  
  
Case 1: 3 1
 


题意:

给定n个块,编号从1到n,以及m个操作,初始时n个块是白色。

操作有2种形式:

1 ai xi : 从[1,ai]选xi个块,将这些块涂白。

2 ai xi:从[ai,n]选xi个块,将这些块涂白。

可以忽略某些操作且如果区间内没有足够的黑块(黑块用于涂白),则不能进行这个操作。

分析:

写写画画一看就知道这道题是一个背包问题。

“恰好装满背包”。

以下摘自题解:

 

本题难点在于正确处理两种操作,不妨假设只有一种操作,那么这种操作如果是1的话那么就把操作按照a从小到大排序,每次都尽量往最左边涂,如果是2的话则类似的涂到最右边,但本题两种操作都出现了。

先考虑第一问:

我们把所有的操作按类别区分开,假设所有的1操作尽量用上能从1涂到a格子,所有的2操作尽量用上能从b格子涂到n,假设a<b,那么答案显然是a+n-b+1。那么假设a>=b,那么假设1操作从1涂到x,那么2操作一定会从n尽量往左边涂,直到x为止。最后两边的总和就是答案。

由上不难想到一个DP,l[i][j]表示用了前i种1操作,从1涂到j的最小操作数,转移l[i][j]=min(l[i][j],l[i-1][j-ope[i].x]+1)(ope[i].x<=j<=ope[i].a),类似的,我们可以得到r[i][j]表示用2操作从j涂到n需要的最小操作数。dp复杂度O(n*m)。(这个背包也可以压缩一维,后面的l,r均为1维的状态)

那么我们倒着枚举涂色最大的数目,假设为k,这个数目必然由1操作贡献一部分,由2操作贡献一部分(也可能一个贡献全部,另一个为0),那么我们枚举1操作涂到了i,那么2操作必然涂到了n-(k-i)+1,如果l[i]和r[n-(k-i)+1]均有值,那么说明这个最大数目是可达的,即是第一问的答案。枚举复杂度O(n*n)。

再考虑第二问:

现在我们已经知道最大数目了,这个数目是由操作1和操作2一起贡献的,那么我们仍然可以枚举操作1涂到了i,那么操作2涂到了n-(ans-i)+1,如果l[i]和r[n-(k-i)+1]均有值,那么其和可以用来更新第二问的答案,最后第二问的答案为所有合法方案需操作数的最小值。枚举复杂度O(n*n)。

代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#define LL long long

using namespace std;

#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));

const int N=1200000;
const int maxn=100000;

const LL mod=998244353;
const int INF = 0x3f3f3f3f;

struct Node
{
    int e;
    int num;

    Node(){}
    Node(int a,int b)
    {
        e=a,num=b;
    }
};


Node nd1[1200],nd2[1200];
int cnt1,cnt2;

bool cmp(Node x,Node y)
{
    return x.e<y.e;
}

int d1[1200];
int d2[1200];



int main()
{
    int T,n,m;
    int cas=1;

    int a,b,c;

    scanf("%d",&T);
    while(T--)
    {
        cnt1=cnt2=0;
        
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&c,&a,&b);

            if(c==1)
            {
                nd1[cnt1++] = Node(a,b);
            }else
            {
                nd2[cnt2++] = Node(n-a+1,b);
            }
        }

        sort(nd1,nd1+cnt1,cmp);
        sort(nd2,nd2+cnt2,cmp);

        memset(d1,0x3f3f3f3f,sizeof(d1));
        d1[0]=0;

        for(int i=0;i<cnt1;i++)
        {
            for(int j = nd1[i].e;j>=nd1[i].num;j--)
            {
                d1[j] = min(d1[j],d1[ j-nd1[i].num ] +1);
            }
        }

         memset(d2,0x3f3f3f3f,sizeof(d2));
         d2[n+1]=0;

         for(int i=0;i<cnt2;i++)
         {
             for(int j=nd2[i].e; j>= nd2[i].num;j--)
             {
                 d2[n+1-j] = min(d2[n+1 -j] ,d2[n+1 - j +nd2[i].num] +1);
             }
         }

//         for(int i=1;i<=n;i++)
//         {
//             printf("d1[%d] = %d  d2[%d] =%d\n",i,d1[i],i,d2[i]);
//         }

         int ans=-1,tmp,re,cc;
         for(int i=0;i<=n;i++)
         {
             for(int j=i+1;j<=n+1;j++)
             {
                 tmp = i + n-j +1;

                 if(tmp < ans) break;

                 tmp=0;cc=0;

                 if(d1[i]!=INF) {tmp +=i;cc+=d1[i];}
                 if(d2[j]!=INF) {tmp +=(n-j+1);cc+=d2[j];}

               //  if(d1[i]!=INF&&d2[j]!=INF)
                 {
                     if(tmp > ans)
                     {
                         ans =tmp;

                         re = cc;
                     }else if(tmp==ans)
                     {
                         re =min(re,cc);
                     }

                 }
             }
         }
         printf("Case %d: ",cas++);
         printf("%d %d\n",ans,re);

    }

    return 0;
}






Problem Description
  There are n boxes in one line numbered 1 to n, at the beginning, all boxes are black. Two kinds of operations are provided to you:

1 a i x i :You can choose any x i black boxes in interval [1,a i], and color them white;
2 a i x i :You can choose any x i black boxes in interval [a i,n], and color them white;

  lcq wants to know if she use these operations in optimal strategy, the maximum number of white boxes she can get, and if she get maximum white boxes, the minimum number of operations she should use.
Tips: 
1. It is obvious that sometimes you can choose not to use some operations.
2. If the interval of one operation didn’t have enough black boxes, you can’t use this operation.
 

Input
  The first line contains one integer T, indicating the number of test case.
  The first line of each test case contains two integers N (1 <= N <= 1000) and M (1<=M<=1000), indicating that there are N grids and M operations in total. Then M lines followed, each of which contains three integers s i(1<=s i<=2) , a i and x i (0 <= x i <= N,1<=a i<=N), si indicating the type of this operation, a i and x i indicating that the interval is [1,a i] or [a i,n](depending on s i), and you can choose x i black boxes and color them white.
 

Output
  For each test case, output case number first. Then output two integers, the first one is the maximum boxes she can get, the second one is the minimum operations she should use.
 

Sample Input
   
   
1 5 2 2 3 3 1 3 3
 

Sample Output
   
   
Case 1: 3 1
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值