码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4381 背包

时间:2015-02-12 22:46:49      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=4381

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 ai xi :You can choose any xi black boxes in interval [1,ai], and color them white;
2 ai xi :You can choose any xi black boxes in interval [ai,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 si(1<=si<=2) , ai and xi (0 <= xi <= N,1<=ai<=N), si indicating the type of this operation, ai and xiindicating that the interval is [1,ai] or [ai,n](depending on si), and you can choose xi 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
/**
hdu 4381 背包变形
题目大意:给定一个区间1~n,所有n个点都是黑色,操作:1 a b 把1~a区间内的b个点变成白色,2 a b 把a~n之间的b个点变成白色,若给定区间黑点数目
           不足b个,则该操作不能执行,问最多能变成多少白色,若变成最多的白色那么最少的操作数是多少?
解题思路:我们把1~a操作的区间按a值递增排序,每次先涂最左边的,dp[j]表示用涂满前j个点的最少操作数,状态转移方程为:dp1[j]=min(dp1[j],dp1[j-p1[i].num]+1);
           a~n的区间做一个转换后和1~a一样操作。然后枚举涂的个数i即可,dp1[j]+dp2[i-j]<=m,有效。其中i:1~n,j:0~i
*/
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;
struct note
{
    int x,num;
    bool operator < (const note &other)const
    {
        return x<other.x;
    }
} p1[1005],p2[1005];

int n,m,dp1[1005],dp2[1005];

int main()
{
    int T,tt=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        int k1=0,k2=0;
        for(int i=0; i<m; i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            if(u==1)
            {
                p1[k1].x=v;
                p1[k1++].num=w;
            }
            else
            {
                p2[k2].x=n+1-v;
                p2[k2++].num=w;
            }
        }
        sort(p1,p1+k1);
        sort(p2,p2+k2);
        memset(dp1,0x3f3f3f,sizeof(dp1));
        memset(dp2,0x3f3f3f,sizeof(dp2));
        dp1[0]=dp2[0]=0;
        for(int i=0; i<k1; i++)
        {
            for(int j=p1[i].x; j>=p1[i].num; j--)
            {
                dp1[j]=min(dp1[j],dp1[j-p1[i].num]+1);
            }
        }
        for(int i=0; i<k2; i++)
        {
            for(int j=p2[i].x; j>=p2[i].num; j--)
            {
                dp2[j]=min(dp2[j],dp2[j-p2[i].num]+1);
            }
        }
        int tmp,ans=0,sum=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=i;j++)
            {
                tmp=dp1[j]+dp2[i-j];
                if(tmp<=m)
                {
                    if(ans!=i)
                    {
                        ans=i;
                        sum=tmp;
                    }
                    else
                    {
                        sum=min(sum,tmp);
                    }
                }
            }
        }
        printf("Case %d: %d %d\n",++tt,ans,sum);
    }
    return 0;
}


hdu 4381 背包

标签:

原文地址:http://blog.csdn.net/lvshubao1314/article/details/43772983

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!