抽签
二分优化
cpp
void solve(int cycle){
int n,m;
cin >> n >> m;
int num[n+1];
rep(i,1,n) cin >> num[i];
int preSum[n*n+5];
rep(i,1,n){
rep(j,1,n){
preSum[i*n+j] = num[i] + num[j];
}
}
sort(preSum+1, preSum+n*n);
rep(i,1,n){
rep(j,i + 1,n){
dbg(num[i], num[j]);
auto pos = lower_bound(preSum+1, preSum+n*n, m - num[i] - num[j]);
if(*pos == m - num[i] - num[j]){
cout << num[i] << " " << num[j] << " " << *pos << endl;
exit(0);
}
}
}
cout << "NO\n";
}深度优先搜索
cpp
int n,k;
int a[10];
int his[10];
bool dfs(int i,int sum){
//if(i == 4)
dbg(i,sum);
if(i == n){
return (sum == k);
}
if(dfs(i+1,sum)){
return true;
}
if(dfs(i+1,sum+a[i])){
his[i] = a[i];
return true;
}
return false;
}
void solve(int cycle){
cin >> n;
for(int i = 0;i<n;i++){
cin >> a[i];
}
cin >> k;
if(dfs(0,0)){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
for(int i = 0;i<n;i++){
cout << his[i] << " ";
}
}哈夫曼树贪心
cpp
#include <iostream>
#include <queue>
using namespace std;
using ll = long long;
priority_queue<ll, vector<ll>, greater<ll>> pq;//创建一个小根堆
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
pq.push(x);
}//将结果放入优先队列中(小根堆),反向构建哈夫曼树
ll ret = 0;
while (pq.size() > 1)
{
ll x = pq.top();
pq.pop();
ll y = pq.top();
pq.pop();
ret += x + y;//有几层就会加几层
pq.push(x + y);
cout << x + y << " ";
}
cout << ret << endl;
return 0;
}对顶堆
cpp
void solve(int cycle){
int n;
cin >> n;
int k = 1;
rep(i,1,n){
int x;
cin >> x;
if(b.empty() || x >= b.top()){
b.push(x);
}else{
a.push(x);
}
k = (i + 1) / 2;
while(b.size() > k){
a.push(b.top());
b.pop();
}
while(b.size() < k){
b.push(a.top());
a.pop();
}
if(i % 2 != 0){
cout << b.top() << endl;
dbg(k);
}
}
}单调队列
P1886 滑动窗口 /【模板】单调队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这里
cpp
int main(){
int n,k;
cin >> n >> k;
vector<int> num(n + 1);
rep(i,1,n) cin >> num[i];
vector<int> ans_min;
vector<int> ans_max;
deque<int> dq;//warning : the deque save i-th number
for(int i = 1;i<=n;i++){
// deque in
while(!dq.empty() && num[dq.back()] <= num[i]){
dq.pop_back();//let small number get out
}
dq.push_back(i);
if(i - dq.front() >= k){
//eg. let i_th = [1,2,3,4] and k = 3
//the length of a region is 4 - 1 = 3
//so we need to pop the first number
dq.pop_front();
}
if(i >= k){
ans_max.push_back(num[dq.front()]);
}
}
deque<int> dq2;
for(int i = 1;i<=n;i++){
while(!dq2.empty() && num[dq2.back()] >= num[i]){
dq2.pop_back();
}
dq2.push_back(i);
if(i - dq2.front() >= k){
dq2.pop_front();
}
if(i >= k){
ans_min.push_back(num[dq2.front()]);
}
}
for(auto &x : ans_min) cout << x << ' ';
cout << endl;
for(auto &x : ans_max) cout << x << ' ';
cout << endl;
}