贪心算法—Problem B&I
题意
要处理一些木棍,第一根的时间是1分钟,另外的,在长度为l,重为w的木棍后面的那根的长度为l', 重量w',只要l <=l' 并且w <= w',就不需要时间,否则需要1分钟,求如何安排处理木棍的顺序,才能使花的时间最少。
解题思路
运用贪心算法。先把这些木棍按长度和重量都从小到大的顺序排列。设length1和weight1是第一根的长度和重量,依次比较后面的是不是比当前的length1,weight1大,是的话把标志flag设为1,并跟新length1,weight1比较。比较完后,再从前往后扫描,找到第一个标志位为0的,作为是第二批的最小的一根,计数器加一。把它的长度和重量作为当前的length1,weight1,再循环往后比较。直到所有的都处理了。
感想
把长度和重量排好序后,关于如何在进行下一轮筛选时遇到了问题,用过指针太复杂也没能实现,加入标志位后通过标志位来筛选比较过的木块果然解决了问题。感觉题目很难,再接再厉。
AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#define SIZE 5000
using namespace std;
struct sticks{
int length;
int weight;
int flag;
}stick[SIZE];
bool cmp(sticks a,sticks b)
{
if(a.length==b.length) return a.weight<b.weight;
else if(a.length<b.length)return true;
else return false;
}
int main()
{
int T,n;
cin>>T;
for(int i=0;i<T;i++)
{
cin>>n;
int j,k;
int time =0;
int length1;
int weight1;
memset(stick,0,sizeof(stick));
for(j=0;j<n;j++)
{
cin>>stick[j].length>>stick[j].weight;
}
sort(&stick[0],&stick[n],cmp);
stick[0].flag = 1;
length1=stick[0].length;
weight1=stick[0].weight;
time= 1;
for(j= 1; j < n; j++)
{
for(k= j; k < n; k++)
{
if(!stick[k].flag&&stick[k].length>=length1&&stick[k].weight>=weight1)
{
length1 = stick[k].length;
weight1 =stick[k].weight;
stick[k].flag = 1;
}
}
for(k=1;k<n;k++)
{
if(!stick[k].flag) break;
}
j = k;
if (j== n) break;
length1 = stick[j].length;
weight1= stick[j].weight;
stick[j].flag= 1;
time++;
}
cout<<time<<endl;
}
}