2017 ICPCECIC 北方邀请赛 H MJF wants to work (贪心)

2024-01-03 13:38

本文主要是介绍2017 ICPCECIC 北方邀请赛 H MJF wants to work (贪心),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MJF wants to work

时间限制: 1 Sec   内存限制: 128 MB
提交: 87   解决: 16
[ 提交][ 状态][ 讨论版]

题目描述

MJF feel the summer vacation is very leisure. So he wants to work to earn money.
There are n jobs MJF can take part in.For job i, it has the start time ti.x, the end time ti.y and reward ci.
MJF wants to take part in two jobs (exact two jobs), and he wants to earn exactly M yuan. He doesn't want to earn one money more,he thinks it's a waste.
Becase MJF is a lazy boy, so he wants the time of the sum of two jobs shortest.
Becase MJF can only take part in one job in a time.So two jobs can't overlap.(ti.y < tj.x)

输入

The input consists of multiple test cases. 
For each test,the first line contains 2 integers n, m.(1 <= n, m <= 2e5)
Then following n lines, each line contains 3 integers ti.x, ti.y, ci.(1 <= ti.x, ti.y, ci <= 2e5)

输出

For each test case, print the value of the sum of two jobs' time.if there are no answer,please print"oh no!"

样例输入

3 10

1 2 3

3 4 7

4 6 7

1 10

1 10 10

样例输出

4

oh no!

123


思路为:

把 时间段 从线段 化成 左右两个端点 问题,   每个端点存 时间, 金钱 和 区分左右标志,  

然后按照 左端点从小到大排序, 并且是 一左一右  排序,  遇到左端点, 维护ans 值,  dp数组存的是 时间,   维护 m- 当前已挣得钱的  时间  尽可能小

遇到右端点  维护 dp 时间


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};int n,m;
int cont;
int dp[maxn*2];// dp数组存的是时间
struct node{int x;int time;int mo;int flag;//0 左端点, 1 右端点
}a[maxn*2];
int cmp(node a,node b)
{if(a.x==b.x)return a.flag<b.flag;return a.x<b.x;}
void init()
{for(int i=0;i<=maxn;i++)dp[i]=INF;int x,y,z;mem(a,0);cont=0;for(int i=1;i<=n;i++){scanf("%d %d %d",&x,&y,&z);a[++cont].x=x;a[cont].time=y-x+1;a[cont].flag=0;a[cont].mo=z;a[++cont].x=y;a[cont].time=y-x+1;a[cont].flag=1;a[cont].mo=z;}sort(a+1,a+cont+1,cmp);int ans=INF;for(int i=1;i<=cont;i++){if(a[i].flag==0)ans=min(ans,dp[m-a[i].mo]+a[i].time);elsedp[a[i].mo]=min(dp[a[i].mo],a[i].time);}if(ans!=INF)printf("%d\n",ans);elseprintf("oh no!\n");}
int main()
{while(~scanf("%d %d",&n,&m)){init();}return 0;
}

Coach's plan

时间限制: 2 Sec   内存限制: 128 MB
提交: 57   解决: 15
[ 提交][ 状态][ 讨论版]

题目描述

NEUACM team holds summer training every year. This year n  students participate in the training, and we provide m computers. Everyone has a suitability (0<=suitability<=1000) to every computer.
Now our coach needs to draw up a plan, which satisfies:
1. every student uses one computer, and a computer can be used by no more than one student;
2. maximize the minimum suitability, which means if the answer is w, then everyone's suitability to his computer shouldn't be less than w.

Hint: huge input, please use fast IO.

输入

The first line contains n and m (1<=n<=m<=500), indicating the number of students and computers.

Next n lines describes every student's suitability to every computer, number in ith line and jth row means student[i]'s suitability to computer[j].

输出

A single number w in one line, which is described before.

样例输入

1 2
1 10
2 3
10 1 2
2 1 1

样例输出

10
2

  找 列最小 水过的,  隔壁 找行最小  水过的,  然后 重判后  game over     隔隔壁,  找行列 最小  依然坚挺 ; mmp


水过代码: 找 行小列小,  min 最小的,

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;int n,m,a[505][505],b[505],c[505];bool cmp(int x, int y){return x > y;
}int main(){while(~scanf("%d%d",&n,&m)){for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++)scanf("%d",&a[i][j]);}for(int i = 0; i < n; i ++){int mxx = a[i][0];for(int j = 1; j < m; j ++)mxx = max(a[i][j],mxx);b[i] = mxx;}for(int j = 0; j < m; j ++){int mxx = a[0][j];for(int i = 1; i < n; i ++)mxx = max(a[i][j],mxx);c[j] = mxx;}sort(b,b+n,cmp);sort(c,c+m,cmp);printf("%d\n",min(c[n-1],b[n-1]));}return 0;
}


正解是: 二分图匹配 + 二分查找;


把网格 从 一维 变成 二维 匹配  问题,   用到匈牙利算法, 

比赛时,  考虑到 二分图匹配,  没 想到 要用到二分查找,  

要用 链式前向星  存储 边l

1w  小心   , 一不小心 就超时;

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};int n,m;
int maps[505][505];
struct Edge{int v,u;
}a[maxn];
int edge_cont;
int head[10005];
int match[10005];
bool used[10005];
void add(int u,int v)
{a[++edge_cont].v=v;a[edge_cont].u=head[u];head[u]=edge_cont;
}
int finds(int x)
{used[x]=1;for(int i=head[x];i!=-1;i=a[i].u)// 链式前向星 访问{int v=a[i].v;int w=match[v];if(w<0||!used[w]&&finds(w))// v 还没匹配 或者 能够找到更合适的{match[x]=v;match[v]=x;return 1;}}return 0;
}
int binary_match()//二分匹配
{int ans=0;mem(match,-1);for(int i=0;i<n;i++){if(match[i]<0)//未匹配{mem(used,0);if(finds(i))//可以找到合适的ans++;}}return ans;
}
bool judge(int x)
{edge_cont=0;mem(head,-1);for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(maps[i][j]>=x){add(i,j+n); //无向图add(j+n,i);}}}if(binary_match()==n)return true;return false;
}
void work()
{int ans;int l=0;int r=1001;while(r-l>1){int mid=(l+r)>>1;if(judge(mid))l=mid;elser=mid;}cout<<l<<endl;
}
int main()
{while(~scanf("%d %d",&n,&m)){mem(maps,0);mem(a,0);min_num=INF;max_num=0;for(int i=0;i<n;i++)for(int j=0;j<m;j++){scanf("%d",&maps[i][j]);}work();}return 0;
}


123

这篇关于2017 ICPCECIC 北方邀请赛 H MJF wants to work (贪心)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/565877

相关文章

上海邀请赛 A题目 HDU 5236(dp)

先求出没有ctrl+s的时候构造长度为i的期望f[i] 。然后枚举保存的次数,求出最小即可。 #include<cstdio>#include<cstdio>#include<cmath>#include<queue>#include<stack>#include<string>#include<cstring>#include<iostream>#include<map>

贪心推公式——AcWing 125. 耍杂技的牛

贪心推公式 定义 贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,希望通过局部的最优选择来得到全局最优解的算法策略。 运用情况 问题具有最优子结构,即一个问题的最优解包含其子问题的最优解。可以通过局部最优决策逐步推导到全局最优。问题的选择策略相对明确且易于计算。 注意事项 贪心算法并不总是能得到全局最优解,可能会陷入局部最优。对于一些复杂问题,需要谨慎验证其正确性。可能需要对

visual studio 2017使用libevent的准备步骤

本人使用的visual studio 2017为community版本,libevent为github上pull下来的最新版本,链接如下:https://github.com/libevent/libevent。 步骤一,编译libevent库 在开始菜单--->所有程序处打开VS 2017的开发人员命令提示符程序,如下图所示 使用cmd命令定位到libevent的目录,输入 nma

2017-1-1

console.info('信息'); http://wenku.baidu.com/view/f7d18d8702d276a200292eed.html

【牛客网 2017年校招模拟笔试(第一场)】超级素数幂

超级素数幂 描述 如果一个数字能表示为p^q(^表示幂运算)且p为一个素数,q为大于1的正整数就称这个数叫做超级素数幂。现在给出一个正整数n,如果n是一个超级素数幂需要找出对应的p,q。 输入 输入一个正整数n(2 ≤ n ≤ 10^18) 分析 暴力枚举幂q,将n开q次方之后得到p,检查p是否为素数,并且检查p的q次幂是否等于n。 *要注意精度问题,代码待之后补充。

【牛客网 2017年校招模拟笔试(第一场)】 序列和

求序列和 描述 我们要找连续的一段长度大于等于L小于等于100整数和等于N,容易观察到合法的长度范围很小,于是我们从L开始枚举,然后找到第一个输出即可。 我的代码 最初提交了一次代码,用vector保存了所有满足条件的序列,输出长度最小的,提交之后说内存超出限制,看了一眼题目,发现内存貌似是限制在2w多k?伤心,之前做题没遇到过内存还有这么严格的限制。 修改了一下,其实这个代码并没

xamarn.android binding parse sdk for a week to work

Xamarin.Android PackageName 需要设置为项目命名空间且全小写。 http://blog.csdn.net/jameszhou/article/details/41806377

代码随想录第31天|贪心算法

134. 加油站 参考 思路: 以每个油站相差作为判断, 比如: gas [5 8 2 8]cost [6 5 6 6] [-1 3 -4 2] 错误 : 把相差最大点当作起点判断能否绕一圈 : 相加数组是否小于0局部最优: 当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行全局最优: 找到可以跑一圈的起始位置 class

贪心算法—

贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。这种算法并不总是能找到全局最优解,但在某些问题上能提供足够好的解决方案。贪心算法的关键特性包括: 局部最优选择:在每一步决策时,都选择当前看来最佳的解决方案,不考虑长远的影响。无后效性:过去做出的选择不会影响未来的选择,也就是说,当前的最优选择不会因为之前做了

算法之广度优先,深度优先,拓扑,贪心,并查集

文章目录 1 图算法1.1 广度优先搜索1.2 深度优先搜索1.3 拓扑排序1.4 贪心算法1.4.1 定义1.4.2 示例 1.5 并查集(不相交集合数据结构)1.5.1 并查集讲解1.5.2 Kruskal算法1.5.3 Prim算法 1.8 Bellman-Ford算法 1 图算法 地图数据常常可以用图(Graph)这类数据结构表示,那么在图结构中常用的搜索算法也可以应用