743A:Vladik and flights
題意簡述
有
在同家公司的機場間行動不耗代價,在不同公司的機場間移動,從
問從
數據範圍
思路
水。
代碼
#include<cstdio>
using namespace std;
int n,a,b;
char st[100010];
int main()
{
scanf("%d%d%d",&n,&a,&b);
scanf("%s",st+1);
if (st[a]==st[b])
printf("0");
else
printf("1");
return 0;
}
743B:Chloe and the sequence
題意簡述
數列
第
求第
數據範圍
思路
經過觀察可以發現。
答案即爲
代碼
include<cstdio>
using namespace std;
int n;
long long k;
int main()
{
scanf("%d%I64d",&n,&k);
for (int i=0;i<=n;i++)
if (k&(1LL<<i))
{
printf("%d",i+1);
break;
}
return 0;
}
743C:Vladik and fractions
題意簡述
給出
數據範圍
思路
這個題比較有意思…
首先
然後瞬間聯想到裂項項消……
於是答案就是
一看
代碼
#include<cstdio>
using namespace std;
int n;
int main()
{
scanf("%d",&n);
if (n==1)
printf("-1");
else
printf("%d %d %d\n",n,n+1,n*(n+1));
return 0;
}
743D:Chloe and pleasant prizes
題意簡述
給出一棵
求兩個不相交的子樹,權值和的最大值。
如果沒有這樣的方案,輸出
數據範圍
思路
樹形DP。
DP出
以一個節點爲根的答案一定是它所有孩子的
所有的答案掃一遍就行了。
注意一條鏈的情況無解。
代碼
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define INF 1LL<<60
struct edge{
int s,t,next;
}e[400010];
int head[200010],cnt;
void addedge(int s,int t)
{
e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++;
e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;
}
int n,u,v;
long long sum[200010],mx[200010];
int size[200010],val[200010];
long long ans=-INF,se;
void dfs(int node,int lastfa)
{
sum[node]=val[node];
size[node]=0;
for (int i=head[node];i!=-1;i=e[i].next)
if (e[i].t!=lastfa)
{
dfs(e[i].t,node);
sum[node]+=sum[e[i].t];
size[node]++;
}
mx[node]=-INF;
se=-INF;
for (int i=head[node];i!=-1;i=e[i].next)
if (e[i].t!=lastfa)
{
if (mx[e[i].t]>mx[node])
{
se=mx[node];
mx[node]=mx[e[i].t];
}
else if (mx[e[i].t]>se)
se=mx[e[i].t];
}
if (size[node]>1)
ans=max(ans,mx[node]+se);
mx[node]=max(mx[node],sum[node]);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&val[i]);
memset(head,0xff,sizeof(head));
cnt=0;
for (int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
dfs(1,1);
if (ans==-INF)
printf("Impossible");
else
printf("%I64d",ans);
return 0;
}
743E:Vladik and cards
題意簡述
給出
問最長的滿足如下條件的子序列長度:
1.子序列中所有相同元素相鄰。
2.子序列中任意兩種元素的個數之差的絕對值
數據範圍
思路
二分+DP。
我們可以發現,所有元素的出現次數之可能爲
所有我們可以二分這個
如何DP?
首先預處理。
DP數組
1.
2.取
3.取
據此轉移就可以了。
時間複雜度
代碼
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int f[1010][260];
int n,lim,l,r,mid,tmp,ans,now;
int seq[1010],ord[1010],cnt[10],pos[10][1010];
bool judge(int x)
{
tmp=0;
memset(f,0xef,sizeof(f));
f[0][0]=0;
for (int i=1;i<=n;i++)
for (int j=0;j<=lim;j++)
{
f[i][j]=f[i-1][j];
if (j&(1<<seq[i]))
{
now=ord[i];
if (x>0&&now-x+1>=1)
f[i][j]=max(f[i][j],f[pos[seq[i]][now-x+1]-1][j^(1<<seq[i])]+x);
if (now-x>=1)
f[i][j]=max(f[i][j],f[pos[seq[i]][now-x]-1][j^(1<<seq[i])]+x+1);
}
}
if (x==0)
for (int i=0;i<=lim;i++)
tmp=max(tmp,f[n][i]);
else
tmp=f[n][lim];
return tmp>0;
}
int main()
{
scanf("%d",&n);
lim=(1<<8)-1;
for (int i=1;i<=n;i++)
{
scanf("%d",&seq[i]);
seq[i]--;
}
for (int i=1;i<=n;i++)
{
ord[i]=++cnt[seq[i]];
pos[seq[i]][cnt[seq[i]]]=i;
}
l=0,r=n/8;
while (l<=r)
{
mid=(l+r)>>1;
if (judge(mid))
ans=tmp,l=mid+1;
else
r=mid-1;
}
printf("%d",ans);
return 0;
}