A
思路&反思
发现人只有在接受到声音后才会进入咆哮,所以不可以通过二分一个时间后把每个人独立开算 仔细思考发现对于一个人一个人分析过来的他们只有一个最优的情况可以使时间最短,于是可以直接模拟
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll;
const int M=1e5 +5 ;
bool mark[M];
int n,tot;
D k,ans,A[M],B[M],use;
int main(){
scanf ("%lf%d" ,&k,&n);
for (int i=1 ;i<=n;i++)scanf ("%lf" ,A+i);
sort(A+1 ,A+1 +n);A[1 ]+=k;
for (int i=1 ;i<n;i++){
A[i+1 ]-=use;
if (A[i]>=A[i+1 ]){
if (A[i+1 ]+use<=A[i])A[i+1 ]+=use;
if (A[i+1 ]+use<=A[i])A[i+1 ]=A[i+1 ]+use+k;
else A[i+1 ]=A[i]+k;
continue ;
}else {
D d=(A[i+1 ]-A[i])/2 ;
use+=d;
A[i+1 ]=A[i+1 ]-d+k;
}
}
printf ("%.4f" ,use);
return 0 ;
}
小结
在情景感很强的题目中我们一定要仔细分析好题目的限制条件和各种情况后再来解答 同时我们也不要拘泥于一定要利用高端的算发来解决问题,可以寻找最优答案形成的过程来贪心
B
我们发现顺序是对问题的解没有影响的,于是问题就转化成区间的覆盖问题了 如果没有
K
这个限制条件,问题就很简单了。所以开始考虑K
/*
我们定义dp[i] 表示覆盖[1 ,i]区间的最小花费
于是我们有以下的转移方程
1 .对于[1 ,i]的中的l且(A [i]-A [l]>k)
dp[i]=dp[l-1 ]+(A [i]-A [l])
2 .对于(A [i]-A [l-1 ]<=k)时更新
dp[i]=dp[l-1 ]+k
*/
#include<bits/stdc++.h>
#define For(i,a ,b) for(int i=a
using namespace std
const int M=3 e5+5
int n,m,k,A [M],dp[M],l=1 ,mi=1 e9
int main(){
scanf("%d %d %d" ,&m,&k,&n)
For(i,1 ,n)scanf("%d" ,&A [i])
sort(A +1 ,A +1 +n)
For(i,2 ,n){
while (A [i]>=A [l]+k)mi=min(dp[l-1 ]-A [l]+1 ,mi),l++
dp[i]=min(A [i]+mi,dp[l-1 ]+k)
}printf("%d" ,dp[n])
return 0
}
C
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)
#define pb(a) push_back(a)
#define sz(a) a.size()
using namespace std ;
typedef long long ll;
const int M=6e5 +5 ;
const ll INF=(ll)1e18 ;
int h[M],nxt[M],tot,t[M],num;
ll c[M],D[M],A[M][2 ],dis[M],n,m;
bool mark[M];
void Add(int x,int y,ll C){
c[++tot]=C,t[tot]=y,nxt[tot]=h[x],h[x]=tot;
c[++tot]=C,t[tot]=x,nxt[tot]=h[y],h[y]=tot;
}
ll to(ll x){
ll k=sqrt (x);
ll a=k*k,b=k*k-(4 *k-4 )+1 ;
if (k*k==x)return b;
if (x<a+(k+1 ))return b-a-2 +x;
return b-a-4 +x;
}
struct P{
int t;ll c;
bool operator <(const P&A)const {return c>A.c;}
};
ll SP(int S,int T){
priority_queue<P>Q;
for (int i=1 ;i<=num;i++)dis[i]=INF;
dis[S]=0 ;
Q.push((P){S,0 });
while (!Q.empty()){
P to=Q.top();Q.pop();
int x=to.t;
if (x==T)return dis[x];
for (int i=h[x];i;i=nxt[i]){
int y=t[i];ll co=c[i];
if (dis[y]>dis[x]+co){
dis[y]=dis[x]+co;
Q.push((P){y,dis[y]});
}
}
}
}
int main(){
cin >>n>>m;
D[++num]=1 ;
for (int i=1 ;i<=m;i++){
scanf ("%lld" ,&A[i][0 ]);
A[i][1 ]=to(A[i][0 ]);
D[++num]=A[i][0 ];
D[++num]=A[i][1 ];
}D[++num]=n;
sort(D+1 ,D+num+1 );
num=unique(D+1 ,D+num+1 )-D-1 ;
for (int i=1 ;i<=m;i++){
A[i][0 ]=lower_bound(D+1 ,D+1 +num,A[i][0 ])-D;
A[i][1 ]=lower_bound(D+1 ,D+1 +num,A[i][1 ])-D;
Add(A[i][0 ],A[i][1 ],1 );
}
for (int i=1 ;i<num;i++)Add(i,i+1 ,D[i+1 ]-D[i]);
int S=lower_bound(D+1 ,D+1 +num,1 )-D;
int T=lower_bound(D+1 ,D+1 +num,n)-D;
printf ("%lld\n" ,SP(S,T));
return 0 ;
}