Codeforces Round #461 (Div. 2)
Codeforces 922C
题意
给定\(n,k \le 10^{18}\),判断是否对于所有的$ i \le k,n mod i$都是不同的
解题思路
首先\(n\ mod\ 1=0\),为了不相同\(n\ mod\ 2=1\),\(n\ mod\ 3=2\)……
即\(n\ mod\ i=i-1\),\(n+1\ mod\ i=0\)
直接暴力判断对所有的\(i\)是否成立即可,由于阶乘的增长速度很快,检查的次数几乎是常数
AC代码
#include <bits/stdc++.h>
using namespace std;
long long n,k;
bool solve()
{
for (long long i=1;i<=k;i++)
if((n+1)%i)
return false;
return true;
}
int main(int argc, char const *argv[])
{
scanf("%I64d%I64d",&n,&k);
if(solve())
puts("Yes");
else
puts("No");
return 0;
}
Codeforces 922D
题意
给定若干由\(s\)和\(h\)组成的字符串,输出将这些字符串拼接后这样的对的数量的最大值\(i<j,s_i=‘s‘,s_j=‘h‘\)
解题思路
对于两个字符串\(A,B\),相应\(s,h\)的数量分别为\(s_{str},h_{str}\) ,设不算这两个串互相产生的对对答案的贡献的其他贡献为\(W\),则当前对的数量为\(W+s_Ah_B\),交换后为\(W+s_Bh_A\)
因此按照\(s_{str}/h_{str}\)排序后即是最佳拼接方案,随后计算对的数量即可
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=100007;
struct node
{
string str;
long long s,h;
}noise[maxn];
int order[maxn];
bool cmp(int l,int r)
{
return noise[l].s*noise[r].h>noise[l].h*noise[r].s;
}
int main(int argc, char const *argv[])
{
int n;
scanf("%d",&n);
for (int i=0;i<n;i++) order[i]=i;
for (int i=0;i<n;i++)
{
cin>>noise[i].str;
long long s=0,h=0;
for (int j=0;j<noise[i].str.size();j++)
{
if(noise[i].str[j]==‘s‘) s++;
else if(noise[i].str[j]==‘h‘) h++;
}
noise[i].s=s;
noise[i].h=h;
}
sort(order,order+n,cmp);
long long ans=0,bs=0;
for (int i=0;i<n;i++)
for (int j=0;j<noise[order[i]].str.size();j++)
{
if(noise[order[i]].str[j]==‘h‘) ans+=bs;
else if(noise[order[i]].str[j]==‘s‘) bs++;
}
printf("%I64d\n",ans);
return 0;
}
Codeforces 922E
题意
我觉得是本题难点之一,不想写了
思路
即状态dp[i][k]
为经过了\(i\)个树召唤了\(k\)个鸟剩余mana的最大值,状态转移方程为:
\[dp[i][j]=max(dp[i][j],min(dp[i-1][j-k]+X,W+(j-k)\times B)-cost_i\times k)\]
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1007;
long long n,w,b,x;
long long c[maxn],cost[maxn];
long long dp[maxn][10*maxn];
int main(int argc, char const *argv[])
{
scanf("%I64d%I64d%I64d%I64d",&n,&w,&b,&x);
for (int i=1;i<=n;i++) scanf("%I64d",&c[i]);
for (int i=1;i<=n;i++) scanf("%I64d",&cost[i]);
memset(dp,-1,sizeof(dp));
dp[0][0]=w;
for (int i=0;i<=n-1;i++)
{
int j=0;
while(dp[i][j]!=-1)
{
if(i>0)
dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]+x),w+j*b);
else
dp[i+1][j]=min(max(dp[i+1][j],dp[i][j]),w+j*b);
for (int k=1;k<=c[i+1];k++)
{
long long nxt=min(dp[i][j]+(i>0?x:0),w+j*b)-cost[i+1]*k;
if(nxt>=0) dp[i+1][j+k]=max(dp[i+1][j+k],nxt);
}
j++;
}
}
for (int i=1;i<=10001;i++)
if(dp[n][i]<0)
{
printf("%d\n",i-1);
return 0;
}
return 0;
}