bzoj3131 [Sdoi2013]淘金
Posted Forever_goodboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3131 [Sdoi2013]淘金相关的知识,希望对你有一定的参考价值。
[Sdoi2013]淘金
Time Limit: 30 Sec Memory Limit: 256 MB
Description
小Z在玩一个叫做《淘金者》的游戏。游戏的世界是一个二维坐标。X轴、Y轴坐标范围均为1..N。初始的时候,所有的整数坐标点上均有一块金子,共N*N块。
一阵风吹过,金子的位置发生了一些变化。细心的小Z发现,初始在(i,j)坐标处的金子会变到(f(i),fIj))坐标处。其中f(x)表示x各位数字的乘积,例如f(99)=81,f(12)=2,f(10)=0。如果金子变化后的坐标不在1..N的范围内,我们认为这块金子已经被移出游戏。同时可以发现,对于变化之后的游戏局面,某些坐标上的金子数量可能不止一块,而另外一些坐标上可能已经没有金子。这次变化之后,游戏将不会再对金子的位置和数量进行改变,玩家可以开始进行采集工作。
小Z很懒,打算只进行K次采集。每次采集可以得到某一个坐标上的所有金子,采集之后,该坐标上的金子数变为0。
现在小Z希望知道,对于变化之后的游戏局面,在采集次数为K的前提下,最多可以采集到多少块金子?
答案可能很大,小Z希望得到对1000000007(10^9+7)取模之后的答案。Input
共一行,包含两介正整数N,K。
Output
一个整数,表示最多可以采集到的金子数量。
Sample Input
1 2 5
Sample Output
18HINT
N < = 10^12 ,K < = 100000
对于100%的测试数据:K < = N^2
Solution:
看了大佬的博客:http://www.cnblogs.com/lidaxin/p/5234975.html。
1 #pragma GCC optimize("O3") 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <queue> 7 using namespace std; 8 #define mod 1000000007 9 #define N 20050 10 #define M 15 11 long long n,k,num[N*10],size[N*10],ans; 12 struct NODE { 13 int x,y; 14 long long val; 15 NODE(int X=0,int Y=0) {x=X,y=Y,val=1ll*size[num[X]]*size[num[Y]];} 16 friend bool operator < (NODE a,NODE b) {return a.val<b.val;} 17 } ; 18 long long cnt,tmp[N*50],f[M][N*5][2]; 19 int bit[M]; 20 priority_queue <NODE> q; 21 bool cmp(int x,int y) {return size[x]>size[y];} 22 void dfs(int last,int len,long long now) { 23 if(len==bit[0]+1) {tmp[++cnt]=now; return ;} 24 if(!now) return ; 25 for(int i=last; i<=9; ++i) dfs(i,len+1,now*i); 26 } 27 int main() { 28 scanf("%lld%lld",&n,&k); 29 while(n) bit[++bit[0]]=n%10,n/=10; 30 dfs(0,0,1); tmp[++cnt]=0; 31 sort(tmp+1,tmp+cnt+1); cnt=unique(tmp+1,tmp+cnt+1)-tmp-1; 32 f[0][2][0]=1; 33 for(int i=0; i<=bit[0]; ++i) { 34 for(int j=1; j<=cnt; ++j) { 35 for(int h=0; h<=1; ++h) { 36 if(f[i][j][h]) { 37 for(int l=(i==0)?0:1; l<=9; ++l) { 38 f[i+1][lower_bound(tmp+1,tmp+cnt+1,tmp[j]*l)-tmp][h+l>bit[i+1]]+=f[i][j][h]; 39 } 40 } 41 } 42 } 43 } 44 for(int i=1; i<=cnt; ++i) { 45 num[i]=i; 46 for(int j=1; j<bit[0]; ++j) size[i]+=f[j][i][0]+f[j][i][1]; 47 size[i]+=f[bit[0]][i][0]; 48 } sort(num+2,num+cnt+1,cmp); 49 q.push(NODE(2,2)); 50 for(int i=0; !q.empty(); ) { 51 NODE temp=q.top(); q.pop(); 52 ans=(ans+temp.val)%mod; 53 ++i; 54 if(i>=k) break; 55 if(temp.x!=temp.y) { 56 ans=(ans+temp.val)%mod; 57 ++i; 58 if(i>=k) break; 59 } 60 if(temp.x!=temp.y) q.push(NODE(temp.x+1,temp.y)); 61 if(temp.x==2) q.push(NODE(temp.x,temp.y+1)); 62 } printf("%lld\\n",ans); 63 return 0; 64 }
以上是关于bzoj3131 [Sdoi2013]淘金的主要内容,如果未能解决你的问题,请参考以下文章