Hiiragi‘s Sticks
Time Limit: 3 Seconds Memory Limit: 65536 KB
Hiiragi likes collecting sticks. It is said that she has collected m short sticks. One day, she was very excited that she found more sticks from a box under her bed. These new
sticks have n different lengths, while for each length, there are infinite sticks of the same length.
Hiiragi then came up with an idea, that concatenates the new sticks in different ways to form long sticks of all possible lengths no longer than L. Let‘s name the lengths a set S.
Her mother told her that "Use each of your m short sticks to measure each of the lengths in S. When you find a short sticks being able to measure a length in integer times, get the times it takes and denote it as t. I will give you
one candy if you can find one way that uses the following rules to reduce t to 1."
- For a number t, find one of its prime factor p, calculate t1 = t / p.
- Use t1 as the new t and go back to the first step until t reaches 1.
Note: With the same short stick and the same length in S,
two ways are considered to be different iff the reduce processes are not all the same. But it may be counted many times if it‘s another short stick or the length differs.
So here, you are required to calculate how many candies Hiiragi can get at most.
Input
The first line is T ( ≤ 10), the number of test cases.
Next is T test cases. Each case contains 3 lines. The first line contains three integers n, m, L (n ≤ 20, m ≤ 105, L ≤ 106). The second line is n integers indicating the lengths of
each kind of sticks found under the bed. The third line is m integers indicating the sticks Hiiragi originally had. All sticks have length no shorter than 1 and no longer than L.
Output
For each case, print one integer, the number of candies Hiiragi can get at most.
Sample Input
1 2 4 12 4 6 1 3 4 3
Sample Output
16
Hint
In the sample, using sticks of length 4 and 6 can make long sticks of S = {4, 6, 8, 10, 12}.
So, with short stick of length 1, Hiiragi can use the following ways
4 -> 2 -> 1
6 -> 3 -> 1
6 -> 2 -> 1
8 -> 4 -> 2 -> 1
10 -> 5 -> 1
10 -> 2 -> 1
12 -> 6 -> 3 -> 1
12 -> 6 -> 2 -> 1
12 -> 4 -> 2 -> 1
to get 9 candies. Also, with short sticks of length 3, 4 and 3 she can get 2, 3 and 2 candies each. So all she can get is 9 + 2 + 3 + 2 = 16 candies.
题意:一个小朋友,已经有了m根木棍,有一天他在床底下突然又发现了n种木棍,注意是种,每种无限多个,发现的n种木棍可以随意拼凑成任意长度,范围在 1 到 L之间,得到一个集合S。然后用以前有的m根木棍去S中测量拼凑的长木棍,用于测量的木棍必须是S中木棍的因子,即 t=Si / Mi t 要为整数。得到t之后,小朋友的妈妈说,如果小朋友能每次把t除以t的质因数,让t变成 1,那么就能得到一个糖,问最多可以得到几个糖,也就最多多少种测量方法。
#include <iostream> #include <stdio.h> #include <string> #include <cstring> #include <cmath> #include <vector> #include <algorithm> const int MM=1000009; typedef long long ll; using namespace std; bool dp1[MM];//只用 0 1所以用bool,节省内存,int会爆。 ll dp2[MM]; vector<int>p[MM]; int main() { int T; int n,m,L; int a; for(int i=2;i<MM;i++) if(p[i].empty()) { for(int j=i;j<MM;j+=i) p[j].push_back(i);//记下每个数的质因数 } scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&L); memset(dp1,0,sizeof dp1); memset(dp2,0,sizeof dp2); dp1[0]=1;//相减后为0,表示存在这个数,所以标记为1 for(int i=0;i<n;i++) { scanf("%d",&a); for(int j=a;j<=L;j++) dp1[j]|=dp1[j-a];//求出S集合中元素,标记为1 } for(int i=0;i<m;i++) { scanf("%d",&a);//dp2[x]表示,凑成x长度的木棍的方法数 dp2[a]++;//当前存在这个长度,那么t=(x/x)=1,可以获得一个糖 } for(int i=2;i<=L;i++) { for(int j=0;j<p[i].size();j++) dp2[i]+=dp2[i/p[i][j]]; //递推过程,每次都枚举质数被 //12-(/2)->6-(/3)->2-(/2)->1,dp[12]+=dp[12/2];dp[6]已经在之前求出 //12-(/3)->4-(/2)->2-(/2)->1,dp[12]+=dp[12/3];dp[4]已经在之前求出 } ll ans=0; for(int i=1;i<=L;i++) { if(dp1[i]) ans+=dp2[i]; } printf("%lld\n",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
ZOJ 3434 Hiiragi's Sticks