机场检录
//二分
#include <bits/stdc++.h>
using namespace std;
long long n,m,a[100005];
bool check(long long x){
long long t=0;
for(int i=1;i<=n;i++) t+=(x/a[i]);
return t>=m;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin >> a[i];
long long l=0,r=1e13;
while(l<r){
long long mid=(l+r)>>1;
if(!check(mid)) l=mid+1;
else r=mid;
}
cout<<r;
return 0;
}
录制比赛
usaco银
dp,贪心?
按 开始时间/结束时间 排序?
#include <bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}a[205];
bool cmp(node a,node b){
if(a.r==b.r) return a.l>b.l;
return a.r<b.r;
}
int n,s1,s2,cnt;
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].l>>a[i].r;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
if(s1<=a[i].l){
cnt++;
s1=a[i].r;
}
else if(s2<=a[i].l){
cnt++;
s2=a[i].r;
swap(s1,s2);
}
}
cout<<cnt;
return 0;
}
水果
60分 刷表法
for(int j=i+1;j<=i+v[i];j++) d[j]=min(d[j],d[i]+c[i]);
标记永久化 区间更新
填表法 倒填
区间查询 单点更新
a[i]=que(max(i-r[i],0),i-1,1)+v[i];
add(i,1,a[i]);
1.刷表法
用当前天的最优解,更新后面的日期。线段树区间更新,单点求值。
2. 填表法
倒着来,dp[i]表示的从i到n的最小花费。如果要买当前水果,就需要在[i+1,n]这些天里,选择一个最小的dp值即可。
3.树状数组
刷表法中的线段树,可以用树状数组代替。因为前面的天数已经没有用了。更新[L,R]与更新[1,R]一样。
树状数组,更新前缀,查询单点。
4.暴力
还有一种暴力优化,基于刷表法的更新区间[L,R] 从R到L扫描,如果无法更新了,就break。正确性比较显然,但是还是可以通过特意构造数据,让区间跑满。
#include <bits/stdc++.h>
using namespace std;
int n,m,a[50005],b[50005],d[50005];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
d[i]=d[i-1]+a[i];
}
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++){
for(int j=min(n,i+b[i]-1);j>=i&&d[i-1]+a[i]<d[j];j--){
d[j]=d[i-1]+a[i];
}
}
cout<<d[n];
return 0;
}
标签:int,20240202,long,刷表法,训练赛,更新,using,dp,随记
From: https://www.cnblogs.com/Firepaw-cattery/p/18004364