A Marketing Scheme
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int T;
int x,y;
int main(){
cin>>T;
while(T--){
cin>>x>>y;
if(x*2>y)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
B. Reverse Binary Strings
记录前面不匹配后面匹配的节点
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int T,n;
char s[maxn];
int main(){
cin>>T;
int now;
int t1,t2;
bool a1[maxn];
bool a2[maxn];
int ans1,ans2;
int ans;
while(T--){
int n;
cin>>n;
getchar();
scanf("%s",s);
//puts(s);
t1=0;
ans1=0;ans2=0;
for(int i=0;i<n;i++){
if((s[i]-'0')==t1){
a1[i]=true;
}else{
a1[i]=false;
}
a2[i]=!a1[i];
t1=(t1+1)%2;
}
for(int i=1;i<n;i++){
if(a1[i]==true&&a1[i-1]==false)
ans1++;
if(a2[i]==true&&a2[i-1]==false)
ans2++;
}
if(a1[n-1]==false)
ans1++;
else
ans2++;
ans=min(ans1,ans2);
cout<<ans<<endl;
}
}
C. Chef Monocarp
分析一下可以发现取餐的顺序一定是ti小的先
然后dp[i][j]表示时间i内取了j个餐的最小代价,因为一个时间只能取一次餐
所以dp[i][j]由dp[i-1][j]和dp[i-1][j-1]转移而来
wa了好多发后来发现时间上限是2*n不是n
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=210;
int T,n;
int a[maxn];
int dp[2*maxn][2*maxn];
int dis[2*maxn][2*maxn];
int main(){
cin>>T;
while(T--){
memset(dp,inf,sizeof(dp));
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i=0;i<=2*n;i++){
dp[i][0]=0;
}
dp[0][0]=0;
for(int i=1;i<=2*n;i++){
for(int j=1;j<=n;j++){
dp[i][j]=min(dp[i-1][j],(dp[i-1][j-1]+abs(i-a[j])));
}
}
cout<<dp[2*n][n]<<endl;
}
}
别人改成一维dp的代码
我是真没看出来这是个背包。。
D. Minimal Height Tree
假设树可以铺满,按dfs思路逐层计算
(cf题序不是按难度排了么?)
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=2e5+10;
int T,n;
int a[maxn];
int l[maxn];
int num[maxn];
int main(){
cin>>T;
int temp;
int ans;
int now;
a[0]=0;
while(T--){
cin>>n;
memset(l,0,sizeof(l));
now=1;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]<a[i-1])
now++;
l[now]++;
}
int s=1;
int e=1;
int sum=0;
int ans=0;
while(1){
ans++;
for(int i=s;i<=e;i++)
sum+=l[i];
s=e+1;
e=sum;
if(sum==n)
break;
}
cout<<ans<<endl;
}
}
E. Make It Increasing
做法应该是求出包含那几个固定点位,且数字之间留够相应空间的最长上升子序列长度,留够相应空间就是比如在i=2的位置是2,那在i=4的位置起码是4,而不能是3。
对于留空的问题,我们可以直接将数字减去下标,那么我们要求的就是包括这几个固定节点的最长不下降子序列长度
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f;
const int maxn=5e5+100;
int a[maxn],b[maxn],d[maxn],n,m;
bool check(){
for(int i=2;i<=m;i++)
if(a[b[i]]<a[b[i-1]])
return false;
return true;
}
int solve(int l,int r)
{
int len=1;
d[len]=a[l];
for(int i=l+1;i<=r;i++)
{
if(a[i]>=d[len])
d[++len]=a[i];
else
{
int j=upper_bound(d+1,d+1+len,a[i])-d;
if(j!=1)
d[j]=a[i];
}
}
int pos=upper_bound(d+1,d+1+len,a[r])-d-1;
return (r-l+1)-pos;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
a[i]-=i;
}
a[0]=-inf,a[n+1]=inf;
b[0]=0,b[m+1]=n+1;
for(int i=1;i<=m;i++)
scanf("%d",b+i);
if(!check())
return 0*puts("-1");
int ans=0;
for(int i=1;i<=m+1;i++)
ans+=solve(b[i-1],b[i]);
printf("%d\n",ans);
return 0;
}
标题
题意:
给 n 个数的序列 ai,求有多少种 n 个数的排列 pi,使得
a
p
i
max
j
=
1
i
−
1
a
p
j
∉
(
1
2
,
2
)
\frac{a_{p_i}}{\max_{j=1}^{i-1} a_{p_j}}\notin \left(\frac 12, 2\right)
maxj=1i−1apjapi∈/(21,2)