10.28测试
T1 眼镜
Sol
一次转换子串显然其内部的答案不会造成影响。所以实际贡献就在转换的边界形成差异。而一次转换有两个边界,至多造成两个差异,所以直接从左往右扫一遍,与上一位相异则\(ans++\),否则\(cnt++\),最后答案就是\(ans+min(2,cnt)\)
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=500010;
namespace io
{
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
return f?x:-x;
}
inline void print(int x)
{
static int s[20],len=0;
if(x<0)putchar('-'),x=-x;
if(x==0)
{
putchar('0');return;
}
while(x)
{
s[++len]=x%10;
x/=10;
}
for(int i=len;i;i--)putchar(s[i]+'0');
return;
}
}
char s[maxn];
int l,ans,cnt;
int main()
{
freopen("glasses.in","r",stdin);
freopen("glasses.out","w",stdout);
using namespace io;
scanf("%s",s+1);l=strlen(s+1);
ans=1;
for(int i=2;i<=l;i++)
{
if(s[i]==s[i-1])cnt++;
else ans++;
}
ans+=min(2,cnt);
print(ans);putchar('\n');
return 0;
}
T2 FSN
Sol
因为\(f[i]\)很小,直接枚举跑完全背包算每个兵用魔法杀死的花费。然后再把花费拿来和W跑01背包即可。
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=3010;
namespace io
{
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
return f?x:-x;
}
inline void print(int x)
{
static char s[20],len=0;
if(x<0)putchar('-'),x=-x;
if(x==0)
{
putchar('0');return;
}
while(x)
{
s[++len]=x%10;
x/=10;
}
for(int i=len;i;i--)putchar(s[i]+'0');
return;
}
}
int n,m,w;
int g[maxn],k[maxn],l[maxn],f[maxn],t[maxn],ans[maxn];//法伤、法费、血量、法抗、物费
long long len,dp[maxn],sum;
int co[maxn][20];
inline void pre()
{
memset(co,0x3f,sizeof(co));
for(int i=0;i<=10;i++)co[0][i]=0;
for(int gpc=0;gpc<=10;gpc++)
{
for(int i=1;i<=m;i++)
{
if(g[i]<=gpc)continue;
int now=g[i]-gpc;
for(int j=now;j<=2000;j++)
{
co[j][gpc]=min(co[j][gpc],co[j-now][gpc]+k[i]);
}
}
for(int i=1999;i>=0;i--)co[i][gpc]=min(co[i][gpc],co[i+1][gpc]);
}
for(int i=1;i<=n;i++)ans[i]=co[l[i]][f[i]];
return;
}
int main()
{
freopen("fsn.in","r",stdin);
freopen("fsn.out","w",stdout);
using namespace io;
n=read();m=read();w=read();
memset(ans,0x3f,sizeof(ans));
for(int i=1;i<=n;i++)
{
l[i]=read();f[i]=read();t[i]=read();
}
for(int i=1;i<=m;i++)
{
k[i]=read();g[i]=read();
}
pre();
for(int i=1;i<=n;i++)
{
sum+=ans[i];
for(int j=w;j>=t[i];j--)
{
dp[j]=max(dp[j],dp[j-t[i]]+ans[i]);
}
}
sum-=dp[w];
if(sum>=1000000000000000000)printf("02145234\n");
else print(sum),putchar('\n');
return 0;
}
T3 REWRITE
Sol
每个*就把A串分开,然后对于每个单独的船,依次向后跑寻找第一个合法位置即可,复杂度\(O(n^2)\)。
Code(我直接用kmp是有问题的,改成暴力即可,吐槽kmp能得91分还是多测就离谱。)
#include<bits/stdc++.h>
using namespace std;
const int maxn=5010;
char s[maxn],s1[maxn],t[maxn][maxn];
int fail[maxn][maxn],sum,len[maxn],ls,lt;
bool tag[maxn];
inline bool pipei(char x,char y)
{
if(x==y||x=='#'||y=='#')return 1;
return 0;
}
inline void getfail(int x)
{
for(int i=1;i<=len[x];i++)
{
int now=fail[x][i];
while(now&&pipei(t[x][now+1],t[x][i+1])==0)now=fail[x][now];
if(pipei(t[x][now+1],t[x][i+1]))fail[x][i+1]=now+1;
}
return;
}
inline int find(int st,int x)
{
int now=0;
if(len[x]==0)return st-1;
for(int i=st;i<=ls;i++)
{
while(now&&pipei(t[x][now+1],s[i])==0)now=fail[x][now];
if(pipei(t[x][now+1],s[i]))
{
now++;
if(now==len[x])
{
return i;
}
}
}
return -1;
}
int main()
{
// freopen("rewrite.in","r",stdin);
// freopen("rewrite.out","w",stdout);
int T;scanf("%d",&T);
while(T--)
{
scanf("%s%s",s1+1,s+1);ls=strlen(s+1);lt=strlen(s1+1);
sum=1;len[1]=0;
for(int i=1;i<=lt;i++)
{
if(s1[i]=='*')sum++,len[sum]=0;
else if(s1[i]=='#')sum++,len[sum]=0,tag[sum]=1;
else t[sum][++len[sum]]=s1[i];
}
for(int i=1;i<=sum;i++)getfail(i);
int lst=0;bool fagl=0;
for(int i=1;i<=sum;i++)
{
lst=find(lst+1,i);
if(lst==-1)
{
printf("NO\n");
fagl=1;
break;
}
lst+=tag[i];
if(lst>ls)
{
printf("NO\n");fagl=1;
break;
}
}
if(!fagl)printf("YES\n");
}
return 0;
}

浙公网安备 33010602011771号