您的位置:首页 > 其它

【NOIP2014八校联考第1场第2试】大水题(water)

2017-01-15 22:31 344 查看

Description

dzy 定义一个n^2 位的数的生成矩阵A 为一个大小为n*n 且Aij 为这个数的第i*n+j-n位的矩阵。

现在dzy 有一个数n^2 位的数k,他想知道所有小于等于k 的数的n*n 生成矩阵有多少种。(如果不足n^2 位则补前缀零)

Solution

首先要发现一个性质,除去回文数,其他数字反过来只要不超过k,就一定要减去另一个,于是就有递推式

。除以2是因为这样子计算会重复一次。设出fi,0..1,0..1表示当前dp做到了第i位;第二维的0表示1..i位的数字与原串的相同,1为不同;第三维的1表示反过来比后i位大,0为小于等于。转移方程随便推一下就可以了。

Code

const mo=1000000007;
var
a:array[0..1000000] of longint;
f:array[0..1000000,0..1,0..1] of longint;
n,k,i,j,sum,mx:longint;
c:char;
ans,a1,a2:int64;
function p1(x,y:longint):longint;
begin
if x=y then exit(1);exit(0);
end;
function p2(x,y:longint):longint;
begin
if x>y then exit(1);exit(0);
end;
function p3(x,y:longint):longint;
begin
if x<y then exit(0);exit(1);
end;
begin
readln(n);
for i:=1 to n*n do
begin
read(c);a[i]:=ord(c)-48;
mx:=(mx*10+a[i])mod mo;
end;
f[0,1,0]:=1;
n:=n*n;
for i:=0 to n-1 do
begin
for k:=0 to 9 do
begin
f[i+1,0,p2(k,a[n-i])]:=(f[i+1,0,p2(k,a[n-i])]+f[i,0,0])mod mo;
f[i+1,0,p3(k,a[n-i])]:=(f[i+1,0,p3(k,a[n-i])]+f[i,0,1])mod mo;
end;
for k:=0 to a[i+1] do
begin
f[i+1,p1(k,a[i+1]),p2(k,a[n-i])]:=(f[i+1,p1(k,a[i+1]),p2(k,a[n-i])]+f[i,1,0])mod mo;
f[i+1,p1(k,a[i+1]),p3(k,a[n-i])]:=(f[i+1,p1(k,a[i+1]),p3(k,a[n-i])]+f[i,1,1])mod mo;
end;
end;
a1:=(f[n,0,0]+f[n,1,0])mod mo;a2:=(f[n div 2,0,0]+f[n div 2,0,1]+f[n div 2,1,0])mod mo;
ans:=(mx-(a1-a2)*500000004 mod mo+mo)mod mo;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  NOIP 八校联考 DP