hdu 3729 I'm Telling the Truth(贪心)
2014-10-01 18:49
246 查看
题意:有n个人,这n个人要进行排队,每个人有可能站在区间[Li,Ri]的区间,现在求一个站队的序列,要求人数尽可能大,在人数最多的情况下让站队的人的编号的字典序最大。
思路:写完以后看网上的题解都是二分匹配啊。。。只有我用贪心写了么?好吧,感觉这题二分匹配根本不敢想嘛,还是贪心比较好。首先,如果没有让编号字典序最大的要求,那么只要贪心就可以了,按照每个人的L值排序,让L大的在前面,然后贪心地安排位置,尽量让这个人站在更靠右的位置。那么,为了构造一个字典序最大的解,首先贪心去找出一个最大值。然后从后向前枚举最终序列中编号最小的人的编号k,那么可选的人就是k~n,看这些人是否能达到最大值,如果可以,那么就让第一个人是k就行了,接下来,枚举剩下的人中编号最小的,这个值当然是要大于k……这样递归去求出所有的结果就行了。
代码:
思路:写完以后看网上的题解都是二分匹配啊。。。只有我用贪心写了么?好吧,感觉这题二分匹配根本不敢想嘛,还是贪心比较好。首先,如果没有让编号字典序最大的要求,那么只要贪心就可以了,按照每个人的L值排序,让L大的在前面,然后贪心地安排位置,尽量让这个人站在更靠右的位置。那么,为了构造一个字典序最大的解,首先贪心去找出一个最大值。然后从后向前枚举最终序列中编号最小的人的编号k,那么可选的人就是k~n,看这些人是否能达到最大值,如果可以,那么就让第一个人是k就行了,接下来,枚举剩下的人中编号最小的,这个值当然是要大于k……这样递归去求出所有的结果就行了。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<set> #include<cmath> #include<vector> #include<bitset> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-6 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn = 110; struct Node { int L,R,id; Node(int L = 0,int R = 0,int id = 0):L(L),R(R),id(id){} bool operator < (const Node & a) const { return L > a.L; } }node[maxn],a[maxn]; bool vis[maxn]; map<int,int>mp; int ans[maxn],tot,n; int solve(int n) { mp.clear(); sort(a + 1,a + n + 1); bool flag; int cnt = 0; for(int i = 1;i <= n;++i) { flag = false; for(int j = a[i].R;j >= a[i].L;--j) { if(mp.find(j) != mp.end()) continue; mp[j] = 1; flag = true; break; } if(flag) cnt++; } return cnt; } void cal(int pos,int limit) { if(limit > n || pos > tot) return ; for(int i = n;i >= limit;--i) { // if(n - limit + 1 >= tot - i + 1) // continue; int m = 0; for(int j = i;j <= n;++j) a[++m] = node[j]; for(int j = 1;j < pos;++j) a[++m] = node[ans[j]]; if(solve(m) == tot) { ans[pos] = i; cal(pos + 1,i + 1); return ; } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 1;i <= n;++i) { scanf("%d%d",&node[i].L,&node[i].R); node[i].id = i; } for(int i = 1;i <= n;++i) a[i] = node[i]; tot = solve(n); for(int i = n - tot + 1;i >= 1;--i) { int m = 0; for(int j = i;j <= n;++j) a[++m] = node[j]; if(solve(m) == tot) { ans[1] = i; cal(2,i + 1); break; } } sort(ans + 1,ans + tot + 1); printf("%d\n",tot); for(int i = 1;i <= tot;++i) { if(i > 1) printf(" "); printf("%d",ans[i]); } puts(""); } return 0; }
相关文章推荐
- hdu 3729 I'm Telling the Truth(二分匹配_ 匈牙利算法)
- 【HDU】3729 I'm Telling the Truth 离散+最大流
- 二分图的最大匹配-hdu-3729-I'm Telling the Truth
- hdu 3729 I'm Telling the Truth(二分图最大匹配)
- hdu 3729 I'm Telling the Truth(二分图匹配)
- hdu 3729 I'm Telling the Truth(最大匹配)
- HDU 3729 I'm Telling the Truth -- 二分图最大匹配 输出方案
- HDU 3729 — I'm Telling the Truth
- hdu 3729 I'm Telling the Truth
- HDU 3729-I'm Telling the Truth-周赛4补题-二分图最大匹配-邻接表
- HDU 3729 I'm Telling the Truth(二部图最大匹配+结果输出)
- HDU 3729 I'm Telling the Truth(二分图最大匹配)
- 二分图的最大匹配-hdu-3729-I'm Telling the Truth
- hdu 3729 I'm Telling the Truth 二分图匹配
- HDU 3729 I'm Telling the Truth(二分图最大匹配)
- HDOJ 3729 - I'm Telling the Truth 水二分图最大匹配
- 【HDOJ 3729】 I'm Telling the Truth (二分图最大匹配)
- HDU I'm Telling the Truth (二分图最大匹配+字典序最大路径输出(好题))
- HDOJ题目3729 I'm Telling the Truth(二分图)
- HDU 3729I'm Telling the Truth