洛谷P4825
【题意】:
【思路】:
不大,我们可以用
的算法通过此题。
记 表示有多少中方法可以到达 ,则:
时间复杂度正正好是 (准确地说,是不到 )。
【代码】:
int f[110][110],n;
int a[110][110],m;
const int mod=1e9+7;
int main(){
scanf("%d%d%d",&n,&m,&a[1][1]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
f[1][1]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=i+1;k<=n;k++)
for(int l=j+1;l<=m;l++)
if (a[i][j]!=a[k][l])
f[k][l]=(f[k][l]+f[i][j])%mod;
printf("%d",f[n][m]);
return 0;
}
洛谷P4440
【题意】: Little Leticija
正在准备编程考试。虽然她已经解决了很多任务,但还有一个任务尚未解决,所以她正在向你寻求帮助。您将获得单词
和
个查询。在每个查询中,给出正整数
,
,
和
。假设单词
由单词
中位置
和
之间的字母组成,而单词
中位置
和
之间的字母组成单词
。如果你可以以某种方式重新排列单词
中的字母并获得单词
,则必须回答DA
,否则回答NE
。
【思路】: 如果单词
可以通过重组使其含有单词
这么个子串的话,单词
中所有字母的个数都必须
单词
中该字母的个数。那么问题就转化为了:求
的子串
中分别有多少个字母a,b,c,d,e...z
。
直接求当然慢,但是我们可以用前缀和优化。记 表示 中有多少个字母 ,则 中含有 这么多个字母 。
当然,我们可以给所有字母重新编号,就像离散化一样,把A
压缩成0
,把B
压缩成1
……这样就可以大大减少内存的消耗。
【代码】:
int s[50100][30],l,n,A,B;
int C,D;char str[50100];
int main(){
freopen("t1.in","r",stdin);
scanf("%s%d",str+1,&n);
l=strlen(str+1);
for(int i=1;i<=l;i++){
memcpy(s[i],s[i-1],sizeof(s[i]));
s[i][str[i]-'a']++;
}
for(int i=1;i<=n;i++){
scanf("%d%d",&A,&B);
scanf("%d%d",&C,&D);
register bool flag=true;
for(int j=0;j<26;j++)
if (s[B][j]-s[A-1][j]>s[D][j]-s[C-1][j]){
flag=false;break;
}
if (flag) puts("DA");
else printf("NE\n");
}
return 0;
}