hdu 1051 Wooden Sticks

Problem Description

There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows: 

(a) The setup time for the first wooden stick is 1 minute. 
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup. 

You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).

 

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.

 

Output

The output should contain the minimum setup time in minutes, one per line.

 

Sample Input

3 5 4 9 5 2 2 1 3 5 1 4 3 2 2 1 1 2 2 3 1 3 2 2 3 1

 

Sample Output

2 1 3

这是一道典型的贪心题目,看了半天决定用栈来解决,大体思路是,先用结构体将木筷的长度重量存起来,在把筷子的按长度排序,若长度相等,则按重量大小排序,我先把第一个筷子的l,w入栈,然后遍历如果l<=l' and w<=w',那么就出栈并且更新,这样一趟后如果数组原来就有不符合l<=l' and w<=w'的情况,那就把这一值继续入栈并且再遍历一趟数组,当然啦我还要设一个标记数组来判断该点用过没,这样最后栈的长度即为所求,下面自己看代码。 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
struct node
{
	int l,w;
}p[5005];
bool cmp(node a,node b)
{
	if(a.l==b.l)
	    return a.w<b.w;
	return a.l<b.l;
}
int main()
{
	int t;
	int vis[5005];
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		stack<node> q;
		for(int i=0;i<n;i++){
			cin>>p[i].l>>p[i].w;
			vis[i]=0;
		}
		sort(p,p+n,cmp);
		int cnt=1;
		node tmp,temp;
		while(cnt<n)       //cnt表示已经安装好的木棒的数量
		{
			if(!vis[0]){   //先把第一个木棒长度重量入栈,并且标记vis[0]=1
			    temp.l=p[0].l;
			    temp.w=p[0].w;
			    vis[0]=1;
				q.push(temp);			
			}
			for(int i=1;i<n;i++){
				if(q.top().l<=p[i].l&&q.top().w<=p[i].w&&!vis[i]){//如果符合,则出栈,同时将新的木棒的长度重量入栈
					q.pop();
					tmp.l=p[i].l;
					tmp.w=p[i].w;
					q.push(tmp);
					vis[i]=1;
					cnt++;
				}
			}
			for(int i=1;i<n;i++){ //查找上一次第一个不符合而未安装的木棒,并入栈
				if(!vis[i]){
					temp.l=p[i].l;
					temp.w=p[i].w;
					vis[i]=1;
					q.push(temp);
					cnt++;
					break;
				}
			}
		}
		cout<<q.size()<<endl;
	}
	return 0;
}

 后面我想了下,觉得这样做还是有一些些麻烦,下面是我从网上找到的代码,觉得还不错就贴出来了。

 

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100005
struct d
{
    int l,w;
} a[N];
bool cmp(d a,d b)
{
    if(a.l==b.l) return a.w<b.w;
    else return a.l<b.l;
}
int main(void)
{
    int t,n,ans,i,j;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        for(i=0; i<n; i++)
            scanf("%d%d",&a[i].l,&a[i].w);
        sort(a,a+n,cmp);
        for(i=0; i<n; i++)
        {
            if(a[i].l&&a[i].w)
            {
                for(j=i+1; j<n; j++)
                {
                    if(a[i].w<=a[j].w)
                    {
                        a[i].l=a[j].l;
                        a[i].w=a[j].w;
                        a[j].l=0,a[j].w=0;
                    }
 
                }
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值