Description
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; }