【SDOI2013】淘金
来源:互联网 发布:淘宝运营周计划表 编辑:程序博客网 时间:2024/04/27 18:14
题目
小 Z在玩一个 叫做《淘金者》的游戏。游戏的世界是一个 二维坐标 。X轴、Y轴坐标范围均为1..N。初始的时候,所有的整数坐标点上均有一块金子,共 N*N 块。
一阵风吹过, 金子的位置发生了一些变化。细心的小Z发现, 初始 在(i, j) 坐标 处的金子会变到 (f(i),f(j))坐标 处。其中f(x)表示 x各位数字的乘积 ,例如 ,例如 f(99)=81,f(12)=2,f(10)=0。如果金子变化后的坐标不在 1..N 的范围内,我们认为这块金子已经 被移出游戏。 同时可以发现, 对于变化之后的游戏局面, 某些 坐 标上的金子数量可能 不止一块 ,而另外一些坐标上可能已经没有金子 。这次变化 之后, 游戏将不会再对 金子的位置和数量进行改变,玩家可以开始采集工作。
小 Z很懒 ,打算 只进行 只进行 K次采集 。每次采集可以得到某 一个坐标上的所有 金子 ,采集之后该坐标上的金子数变为 0。
现在小 Z希望知道,对于变化之后的游戏局面,在采集次数为K的前提下, 最多可以采集到少块金子?
答案可能很大,小 Z希望得到1000000007 (10^ 9+7) 取模之后的答案。
题意
即让你找k个点是改变后存在的次数最多的和。
分析
我们可以发现这题求的是k个x,y,
1.
仔细一看,其实这道题的坐标是可以分成两部分,然后再处理的。
于是我们便可以求出y=f(x)的个数。
又因为这题的特殊性(y是又1..9之间的数相乘)
所以y是只含有2,3,5,7因子的数,
故我们可以用数位dp求出每个存在的数的出现的次数:
我们设f[i,j,k,l,t,o]为前i位,
o=0,前面组成的数不等于n且小于等于n
o=1,前面组成的数等于n
那么转移便很简单了:
2.
我们设:
a1>a2>a3>a4>a5….atot(ai为存在的数的次数,前文的Sum)
然后我们发现答案加上的数一定是某k个ai*aj
那么现在的问题就是如何快速的算出前k个最大的ai*aj。
这时我们可以用堆处理:
首先把a1与其他的tot-1个数相乘放到堆里,且记录两个相乘的数的下标。(f[i,1]=i;f[i,2]=1;f[i,3]=a[f[i,1]]*a[f[i,2]];)
然后循环k次:取出栈首,且++f[1,2],算出新的f[1,3]=a[f[1,1]]*a[f[1,2]],再放进栈首。
为什么是对的呢?
我们可以这样想:
栈里面的x(f[i,1])不变是因为我们考虑f[i,3]为表示由x组成的没用过的最大值,而我们每次用过了y(f[i,2]),之后的次大值就是y+1.
const mo=1000000007;var f:array[0..14,0..36,0..25,0..25,0..12,0..1] of longint; ch,i,m,j,k,l,r,num,o,p,nu,ew:longint; n,ans,t:int64; an:array[1..240000] of int64;b:array[0..240000,1..3] of int64; bit:array[0..100] of longint; chr:array[0..9,1..4] of longint=( (0,0,0,0),(0,0,0,0),(1,0,0,0),(0,1,0,0),(2,0,0,0),(0,0,1,0),(1,1,0,0),(0,0,0,1),(3,0,0,0),(0,2,0,0));function pd(x,y,z,k:longint):boolean;begin exit((x<37)and(y<26)and(z<26)and(k<13));end;function got(x,y,z,k:longint):integer;var i:longint;o:int64;begin o:=1; for i:=1 to x do begin o:=o*2;if o>n then exit(1);end; for i:=1 to y do begin o:=o*3;if o>n then exit(1);end; for i:=1 to z do begin o:=o*5;if o>n then exit(1);end; for i:=1 to k do begin o:=o*7;if o>n then exit(1);end; if o=n then exit(0) else exit(-1);end;procedure qsort(l,r:longint);var i,j:longint;t,mid:int64;begin mid:=an[(l+r)shr 1];i:=l;j:=r; repeat while an[i]>mid do inc(i); while an[j]<mid do dec(j); if i<=j then begin t:=an[i];an[i]:=an[j];an[j]:=t;inc(i);dec(j);end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r);end;procedure up(x:int64);begin while (x>1)and(b[x,1]>b[x div 2,1]) do begin b[0]:=b[x];b[x]:=b[x div 2];b[x div 2]:=b[0];x:=x div 2; end;end;procedure down(x:int64);var k:int64;begin while ((x*2<=nu)and(b[x,1]<b[x*2,1]))or((x*2+1<=nu)and(b[x,1]<b[x*2+1,1])) do begin k:=x*2; if (k+1<=nu)and(b[k,1]<b[k+1,1]) then k:=k+1; b[0]:=b[x];b[x]:=b[k];b[k]:=b[0];x:=k; end;end;begin read(n,m);t:=n; while t<>0 do begin inc(bit[0]);bit[bit[0]]:=t mod 10;t:=t div 10;end; for ch:=1 to bit[bit[0]] do begin if ch=bit[bit[0]] then p:=1 else p:=0; f[bit[0],chr[ch,1],chr[ch,2],chr[ch,3],chr[ch,4],p]:=1;end; for i:=bit[0] downto 2 do begin for ch:=1 to 9 do f[i-1,chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r,0]:=f[i-1,chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r,0]+1; for j:=0 to 36 do for k:=0 to 25 do for l:=0 to 25 do for r:=0 to 12 do for o:=0 to 1 do if f[i,j,k,l,r,o]>0 then begin for ch:=1 to 9 do begin if pd(chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r) then begin if (o=1)and(ch>bit[i-1]) then break; if (o=1)and(ch=bit[i-1]) then p:=1 else p:=0; f[i-1,chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r,p]:=f[i-1,chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r,p]+f[i,j,k,l,r,o]; ew:=f[i-1,chr[ch,1]+j,chr[ch,2]+k,chr[ch,3]+l,chr[ch,4]+r,p]; if (chr[ch,1]+j=0)and(chr[ch,2]+k=0)and(chr[ch,3]+l=0)and(chr[ch,4]+r=1)and(p=0)and(i-1=13) then ans:=ans; end; end; end; end; num:=0; for i:=0 to 36 do for j:=0 to 25 do for k:=0 to 25 do for l:=0 to 25 do if (got(i,j,k,l)<1) then begin if (f[1,i,j,k,l,0]+f[1,i,j,k,l,1]>0) then begin inc(num);an[num]:=f[1,i,j,k,l,1]+f[1,i,j,k,l,0]; end; end; qsort(1,num);nu:=num; for i:=1 to num do begin b[i,1]:=(an[i]*an[1]);b[i,2]:=an[i];b[i,3]:=1;up(i);end; for i:=1 to m do begin ans:=(ans+b[1,1])mod mo; b[1,1]:=(b[1,2]*an[b[1,3]+1]);b[1,3]:=b[1,3]+1; down(1); end; writeln(ans);end.
- SDOI2013 淘金
- 【SDOI2013】淘金
- 3131: [Sdoi2013]淘金
- 【JZOJ3216】【SDOI2013】淘金
- BZOJ 3131 [Sdoi2013] 淘金
- bzoj 3131: [Sdoi2013]淘金 数位dp+堆
- 淘金
- [Sdoi2013]assassin
- [Sdoi2013]spring
- [Sdoi2013]escape
- [Sdoi2013]项链
- [Sdoi2013]城市规划
- 【SDOI2013】直径
- 【SDOI2013】方程
- 【SDOI2013】项链
- [Sdoi2013]直径
- 【SDOI2013】森林
- SDOI2013 森林
- Brackets安装Emmet插件显示“Internal error”解决办法
- java.io.Serializable接口
- PL/SQL Developer Logon the DB user with ORA-12154
- 闪退捕捉办法
- service介绍之service的使用与本地通信
- 【SDOI2013】淘金
- setNeedsDisplay setNeedsLayout layoutIfNeeded
- 《电子或通信领域当前的主流技术及其社会需求调查报告》
- 入门训练 圆的面积
- 函数对象(function object)的简单讲解
- ubuntu下用 rvm 安装 ruby rails 小记
- 七、常量指针和指针常量
- HDU 5591 (博弈 水~)
- 树形DP入门