#include
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
int n,m,x,y,a,b;
int main()
{
int Q=read();
for (;Q--;)
{
n=read();
x=read();
y=read();
a=read();
b=read();
int low=x-y,high=x+y;
if(low*n<=a+b&&high*n>=a-b) puts("Yes");
else puts("No");
}
return 0;
}
#include
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=2e5+5;
int T,n,k,s[N],a[N];
int main()
{
T=read();
while(T--)
{
n=read(),k=read();
a[0]=a[n+1]=1e9+5;
for ( int i=1;i<=n;++i )
a[i]=read();
for ( int i=1;i<=n;++i)
{
s[i]=s[i-1];
if(a[i]>a[i-1]&&a[i]>a[i+1])
s[i]++;
}
int pos=0,ans=0;
for ( int i=k;i<=n;++i )
if(ans<s[i-1]-s[i-k+1]+1)
{
pos=i-k+1;
ans=s[i-1]-s[i-k+1]+1;
}
printf("%d %d\n",ans,pos);
}
return 0;
}
#include
using namespace std;
const int N=2e5+5;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
int a[N];
signed main()
{
int Q=read();
for (;Q--;)
{
int n=read();
int flg=0;
for ( int i=1;i<=n;i++ ) a[i]=read();
for ( int i=1;i<=n;i++ )
{
int j=i;
while(j+1<=n&&a[j+1]>a[j]) j++ ;
for ( int k=i;k<j;k++ )
if((a[k]+1)^a[k+1])
flg=1;
i=j;
}
if(flg) puts("No");
else puts("Yes");
}
return 0;
}
比较基础的 D P DP DP以及贪心
我们首先设 f i , j f_{i,j} fi,j为到第 i i i块用了 j j j个额外木棒是否能够构成数字。转移就很简单: f i , j ∣ = [ k = 0 9 ] f i − 1 , j − c i , k f_{i,j}|=[_{k=0}^{9}]f_{i-1,j-c_{i,k}} fi,j∣=[k=09]fi−1,j−ci,k。 c i , j c_{i,j} ci,j是:第 i i i块变成数字 j j j的需要木棒数(如果无法变,那么 c i , j = i n f c_{i,j}=inf ci,j=inf),可以预处理得到。
然后我们再用 g i , j g_{i,j} gi,j到第 i i i块用 j j j根木棒需要变成的数字,转移时修改即可。
我们还有一个贪心策略,就是从高位做到低位即可。
#include
#define pb push_back
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=2e3+5;
string s[11]=
{"1110111","0010010","1011101","1011011","0111010","1101011","1101111","1010010","1111111","1111011"};
int n,m,f[N][N],g[N][N],c[N][11],h[N];
string a[N];
inline int calc(int x,int y)
{
int gs=0;
for ( int i=0;i<7;i++ )
{
if(a[x][i]=='1'&&s[y][i]=='0') return 1e9;
else
if(a[x][i]=='0'&&s[y][i]=='1') gs++;
}
return gs;
}
int main()
{
n=read();
m=read();
memset(f,-1,sizeof(f));
int alb=0;
for ( int i=1;i<=n;i++ )
{
cin>>a[i];
for ( int j=0;j<=9;j++ )
{
int flg=1;
for ( int k=0;j<7;k++ )
if(a[i][k]!=s[j][k])
{
flg=0;
break;
}
alb|=flg;
}
}
if(!alb) return puts("-1"),0;
reverse(a+1,a+n+1);
for ( int i=1;i<=n;i++ )
{
for ( int j=0;j<=9;j++ )
c[i][j]=calc(i,j);
int flg=1;
for ( int j=0;j<=9;j++ )
if(c[i][j]!=1e9) flg=0;
if(flg) return puts("-1"),0;
}
// for ( int i=1;i<=n;i++,puts("") )
// for ( int j=0;j<=9;j++ )
// printf("c[%d][%d]=%d\n",i,j,c[i][j]);
f[0][0]=1;
for ( int i=1;i<=n;i++ )
for ( int j=0;j<=m;j++ )
for ( int k=0;k<=9;k++ )
{
int cost=c[i][k];
if(j-cost<0||cost==1e9) continue;
if(~f[i-1][j-cost])
f[i][j]=1,g[i][j]=k;
}
if(!(~f[n][m])) return puts("-1"),0;
for ( int i=n;i>=1;i-- )
{
int x=g[i][m];
// printf("x=%d c[%d][%d]=%d\n",x,i,x,c[i][x]);
printf("%d",x);
m-=c[i][x];
}
return 0;
}
首先我们来感谢素质出题人没对 d i d_i di排序
我们回到这题:我们先设 f i , j f_{i,j} fi,j表示到 d i d_i di,以及对于不完整的一个周期 ( g + r ) (g+r) (g+r)多出 j j j秒的最小周期数(因为周期与周期之间本质相同的)。
然后对于每一个关键点分类讨论(即向左,向右)这边我们具体来讲一下向左。假设此时为 d i d_i di,那么左边即为 d i − 1 d_{i-1} di−1(注意边界),以及不往左走前已经多出来 j j j秒。
如果 ( d i − d i − 1 + j ) < g (d_i-d_{i-1}+j)
如果 ( d i − d i − 1 + j ) = g (d_i-d_{i-1}+j)=g (di−di−1+j)=g,那么 f i − 1 , 0 = f i , j + 1 f_{i-1,0}=f_{i,j}+1 fi−1,0=fi,j+1。应为一个周期满了,需要重开一个(很显然)
到这里我们发现边权只存在 0 , 1 0,1 0,1,那么我们只需要 01 b f s 01bfs 01bfs即可。具体的就是搞个双端队列,对于边权为 1 1 1的 p u s h b a c k pushback pushback否者 p u s h f r o n t pushfront pushfront
#include
#define pb push_back
#define int long long
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=1e6+5;
const int M=1e4+5;
int n,m,d[M],R,G,dis[M][1005],ans;
deque<pair<int,int> >q;
signed main()
{
n=read();
m=read();
for ( int i=1;i<=m;i++ ) d[i]=read();
G=read();
R=read();
sort(d+1,d+m+1);
memset(dis,-1,sizeof(dis));
q.push_front(make_pair(1,0));
dis[1][0]=0;
while(!q.empty())
{
pair<int,int> v=q.front();
q.pop_front();
if(v.first>1)
{
int del=d[v.first]-d[v.first-1]+v.second;
if(del<G)
{
if(dis[v.first-1][del]<0)
{
dis[v.first-1][del]=dis[v.first][v.second];
q.push_front(make_pair(v.first-1,del));
}
}
if(del==G)
{
if(dis[v.first-1][0]<0)
{
dis[v.first-1][0]=dis[v.first][v.second]+1;
q.push_back(make_pair(v.first-1,0));
}
}
}
if(v.first<m)
{
int del=d[v.first+1]-d[v.first]+v.second;
if(del<G)
{
if(dis[v.first+1][del]<0)
{
dis[v.first+1][del]=dis[v.first][v.second];
q.push_front(make_pair(v.first+1,del));
}
}
if(del==G)
{
if(dis[v.first+1][0]<0)
{
dis[v.first+1][0]=dis[v.first][v.second]+1;
q.push_back(make_pair(v.first+1,0));
}
}
}
}
int ans=-1;
for ( int i=0;i<G;i++ )
{
if(dis[m][i]<0) continue;
int gs=dis[m][i];
int tim=1ll*gs*(R+G)+i;
if(!i&&dis[m][i]) tim-=R;
if(ans<0||ans>tim) ans=tim;
}
printf("%lld\n",ans);
return 0;
}