写题解防hack
A. Nastya and Rice
水题略
B. Nastya and Door
队列维护一下就行
C. Nastya and Strange Generator
弄两组指针,分别指向前面和后面,用multiset维护最大值即可
/*
* Author : Jk_Chen
* Date : 2020-04-23-22.58.02
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int a[maxn];
int pos[maxn];
int pre[maxn];
int nex[maxn];
int main(){
int t=rd;
while(t--){
multiset<int>S;
int n=rd;
rep(i,1,n){
a[i]=rd;
pos[a[i]]=i;
pre[i]=i-1;
nex[i]=i+1;
S.insert(1);
}
bool cant=0;
rep(i,1,n){
int p=pos[i];
auto it=S.end();
it--;
int mx=*it;
if(p-pre[p]!=mx){
cant=1;break;
}
int L=pre[p],R=nex[p];
it=S.find(p-pre[p]);
S.erase(it);
pre[R]=L;nex[L]=R;
if(R<=n){
S.insert(R-L);
}
}
if(cant)puts("No");
else puts("Yes");
}
return 0;
}
/*_________________________________________________________end*/
D. Nastya and Scoreboard
用dp[i][j]维护好 用 个火柴是否可行,最后从前往后贪心
/*
* Author : Jk_Chen
* Date : 2020-04-23-23.15.25
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=2e3+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
char* tp[10]={
"1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011"
};
char x[maxn][9];
int nd[maxn][10];
bool dp[maxn][maxn];
int main(){
int n=rd,K=rd;
rep(i,1,n){
scanf("%s",x[i]);
}
rep(i,1,n){
rep(j,0,9){
rep(k,0,6){
if(x[i][k]==tp[j][k])continue;
if(x[i][k]=='0')nd[i][j]++;
else nd[i][j]+=1e7;
}
}
}
dp[n+1][0]=1;
per(i,n,1){
rep(now,0,9){
int need=nd[i][now];
if(need>1e5)continue;
rep(j,need,K){
dp[i][j]|=dp[i+1][j-need];
}
}
}
int cnt=0;
bool yes=0;
rep(i,1,n){
per(now,9,0){
int need=nd[i][now];
if(need>1e5)continue;
if(dp[i+1][K-cnt-need]){
yes=1;
putchar('0'+now);
cnt+=need;
break;
}
}
if(!yes)break;
}
if(!yes)puts("-1");
return 0;
}
/*_________________________________________________________end*/
E. Nastya and Unexpected Guest
将点按照路灯时间拆开,做一遍迪杰斯特拉。过程中时刻维护ans即可。
剪枝: 当前点权大于ans时结束
/*
* Author : Jk_Chen
* Date : 2020-04-23-23.33.46
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e4+3;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int len,n;
int p[maxn];
int dis[maxn][1002];
bool vis[maxn][1002];
int a,b;
struct node{
int d,p,sta;
bool operator<(const node &A)const{
return d>A.d;
}
};
int bfs(){
mmm(dis,0x3f);
priority_queue<node>Q;
if(p[1]>a)return -1;
else if(p[1]<a){
dis[1][p[1]]=p[1];
Q.push({p[1],1,p[1] });
}
else{
dis[1][0]=a+b;
Q.push({a+b,1,0 });
}
int ans=inf;
while(!Q.empty()){
node P=Q.top();Q.pop();
if(vis[P.p][P.sta])continue;
vis[P.p][P.sta]=1;
if(P.sta==0&&len-p[P.p]<=a){
ans=min(ans,dis[P.p][P.sta]+len-p[P.p]);
continue;
}
if(dis[P.p][P.sta]>=ans)continue;
if(P.p>1){
int sub=p[P.p]-p[P.p-1];
if(P.sta+sub<a){
if(dis[P.p-1][P.sta+sub]>dis[P.p][P.sta]+sub){
dis[P.p-1][P.sta+sub]=dis[P.p][P.sta]+sub;
Q.push({dis[P.p-1][P.sta+sub],P.p-1,P.sta+sub});
}
}
else if(P.sta+sub==a){
if(dis[P.p-1][0]>dis[P.p][P.sta]+sub+b){
dis[P.p-1][0]=dis[P.p][P.sta]+sub+b;
Q.push({dis[P.p-1][0],P.p-1,0});
}
}
}
if(P.p<n){
int sub=p[P.p+1]-p[P.p];
if(P.sta+sub<a){
if(dis[P.p+1][P.sta+sub]>dis[P.p][P.sta]+sub){
dis[P.p+1][P.sta+sub]=dis[P.p][P.sta]+sub;
Q.push({dis[P.p+1][P.sta+sub],P.p+1,P.sta+sub});
}
}
else if(P.sta+sub==a){
if(dis[P.p+1][0]>dis[P.p][P.sta]+sub+b){
dis[P.p+1][0]=dis[P.p][P.sta]+sub+b;
Q.push({dis[P.p+1][0],P.p+1,0});
}
}
}
}
if(ans==inf)return -1;
return ans;
}
int main(){
len=rd,n=rd;
rep(i,1,n){
p[i]=rd;
}
sort(p+1,p+1+n);
a=rd,b=rd;
if(len<=b){
printf("%d\n",len);
return 0;
}
printf("%d\n",bfs());
return 0;
}
/*_________________________________________________________end*/