把过去和现在的笔记记录也搬了过来,也算是给以后留个念想吧,想想一开始打acm就是图一乐,后来发现这游戏还挺上头的,也算是度过了一段电竞生涯(xs)
早些时候的笔记写的好中二,连我自己看着都羞耻。
不过,就喜欢这种羞耻的感觉。
收录的题目大部分是个人认为质量不错的题目,以DP为主,非DP的题目都用※进行了标识。
当然,有些题解思路本身也是源自其他人的,不过除非特殊标注,否则都是用的自己的代码。

题目大意:

1619D New Years Problem
题目大意:有n个人和m个商店,p[n][m]表示这个人收到m商店买的东西时的愉悦度,你只能去最多n-1个商店,求min[joy[n]]的最大值。

解:

纯纯的思维题,因为是最小值的最大值,一眼二分,问题是怎么分。
由于要求的是最小值,那么这个值绝对不会大于原本所有joy可能达到的最大值的最小值,所以二分的边界就在0和这个值之内。
既然只能去n-1个商店,而二分的这个值又是<=每个joy的最大值的,说明只要有一个商店可以买到至少两个超过二分值的商品就足够了,剩下的n-2个商店可以随便取。
一开始为了要不要二分而产生了由于,捏了些特殊样例试图贪心,后来发现了答案的数值就是最有能力的判断方式,所以果断二分了。
铁没有1800应有的难度。

代码

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <istream>
#include <map>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
#include <cstring>
#include <string>
#include <fstream>
#define ll long long
#define maxn 300005
#define mdl 1000000007
#define clr(a,n) for(int i=0;i<n;i++)a[i]=0
#define cfast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pll pair<ll,ll>
#define pii pair<int,int>
#define inc(i,a,n) for(int i=a;i<n;i++)
#define vset(a,n,m) for(int i=0;i<n;i++)a[i]=m;
#define endl '\n'
#define PI 3.14159265358979
using namespace std;
ll gcd(ll a, ll b) {
if (a < b)swap(a, b);
if (b == 0)return a;
return gcd(b, a % b);
}
ll cpow(ll x, ll n) {
ll ans = 1;
while (n > 0) {
if (n & 1) ans = (ans * x) % mdl;
x = (x * x) % mdl;
n >>= 1;
}
return ans;
}
ll getpos(int p, ll n) {
return n / cpow(10, p - 1) % 10;
}
ll getwei(ll n) {
int res = 0;
while (n) {
res++;
n /= 10;
}
return res;
}
/*

---------------------------------------------------------------------

*/
vector<ll> p[maxn];
ll mx[maxn];
int main() {
cfast;
int t = 1;
cin >> t;
while (t--) {
int m, n;
cin >> m >> n;
inc(i, 0, n) {
mx[i] = 0;
}
inc(i, 0, m) {
p[i].clear();
inc(j, 0, n) {
ll d;
cin >> d;
p[i].push_back(d);
mx[j] = max(mx[j], d);
}
}
ll left = 0, right = 1e9,ans=0;
inc(i, 0, n) {
right = min(right, mx[i]);
}
while (left <= right) {
ll mid = (left + right) / 2;
int f = 0;
inc(i, 0, m) {
int cnt = 0;
inc(j, 0, n) {
if (p[i][j] >= mid)cnt++;
}
if (cnt >= 2) {
f = 1;
break;
}
}
if (f == 1) {
ans = max(ans, mid);
left = mid + 1;
}
else {
right = mid - 1;
}
}
cout << ans << endl;
}
}
/*
2 3
1 4

*/