Description
(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
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题目要求,给出包含两个关键字的一个序列,最少能够组成多少个两个关键字都为升序的序列。
/*****************************************************************************************************************************************************************************************************
简单的贪心算法问题,由于刚刚接触到贪心算法,对他的本质不够了解。虽然自己写的代码提交后也过掉了,但是看到题解后还是感觉受益匪浅。我写的算法比较容易理解,大家可以参考。后面的贪心 算法,应该是本题的正解。
贪心的基本思路是::首先对两个关键字进行排序。然后第一重 i 循环遍历所有点,如果遇到没有被标记过的点(用 s 数组进行标记),进入第二重循环,比较第二关键字,在保持升序的状态下尽可能多的标记带点。这样进入了几次第二重循环就需要多少时间。
我的思路::首先对两个关键字进行排序。第一重 i 循环遍历所有的点,第二重 j 循环遍历s数组并把 i 的第二个关键字(设为se)计入到 s数组中,(记录的原理是,如果se大于s 数组中的值,就把该值改成se)。这样s中有几个不为0的值,就要花多长时间。
*****************************************************************************************************************************************************************************************************/
首先是我的代码::
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
//const int MAXN = 10010;
//#define INF 0x3FFFFFFF
/*************************************
**************头文件*****************
*************************************/
vector<pair<int,int> > a;//利用vector便于排序
int s[5002];//作用见思路分析
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int l,w;
a.clear();
REP(i,n){
cin>>l>>w;
a.PB(MP(l,w));
}
memset(s,0,sizeof(s)); //初始化s
sort(a.begin(),a.end()); //进行排序
REP(i,n) //遍历每一个点
REP(j,n){ //遍历s数组
if(a[i].second>=s[j]){
s[j] = a[i].second;
break; //当把a[i].second放进数组后就直接break,避免重复操作
}
}
int t = 0;
REP(i,n)
if(s[i] != 0) //当不为0时,必然有a[i].second放到s中
t++;
else break; //当为0时,不然没有a[i].second放到s中,后面的也不会再有
cout<<t<<endl;
}
return 0;
}
下面是通过学习贪心算法写出来的代码
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3F3F3F3F
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
//const int MAXN = 10010;
//#define INF 0x3FFFFFFF
/*************************************
**************头文件*****************
*************************************/
vector<pair<int,int> > a;//利用vector便于排序
int s[5002];//作用见思路分析
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int l,w;
a.clear();
REP(i,n){
cin>>l>>w;
a.PB(MP(l,w));
}
memset(s,0,sizeof(s)); //初始化s
sort(a.begin(),a.end()); //进行排序
int ans = 0; //记录结果
REP(i,n)
{
if(s[i])continue; //如果i被访问过,不再进入二重遍历
s[i] = 1; //没有被访问过的,标记为访问过,并进入二重遍历
int W = a[i].second; //记录第二关键字,便于比较
REP2(j,i,n-1) //i之前的点肯定已经被访问过,无需在进行比较
{
if(!s[j]&&a[j].second>=W)//没有被访问,并且第二关键字升序
{
s[j] = 1; //标记为已经访问
W = a[j].second; //下次循环时,比较这一次的se,保持升序
}
}
ans++; //进入第二重循环就会累加一次
}
cout<<ans<<endl;
}
return 0;
}