ZOJ 3434 Hiiragi's Sticks

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."

  1. For a number t, find one of its prime factor p, calculate t1 = t / p.
  2. 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 ≤ 105L ≤ 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

时间: 2024-11-03 21:55:28

ZOJ 3434 Hiiragi's Sticks的相关文章

ZOJ 1025. Wooden Sticks 贪心 结构体排序

Wooden Sticks Time Limit: 2 Seconds      Memory Limit: 65536 KB There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some

zoj 1025 - Wooden Sticks

题目:求一个序列中最大不上升子序列的个数. 分析:dp,LIS.一个序列中的不上升子序列的最小个数,是他的最大上升子序列长度. 证明:首先求串的最大上升子序列,那么每个元素一定属于一个不同的不下降串: 如果,取第一个最大上升子序列,那么每个元素一定是集合中的最大值: 这些最大值可以分别确定一个不上子串,对应一个集合,所以下界是|LIS|: 然后,假设存在一个集合P,最大值p不在lis中,他不属于上面的集合: 他自己确定一个不上升序列,设他前面的集合的最大值为lis(i): 则有lis(i)>=

ZOJ 1025 Wooden Sticks(贪心 基础题)

题目链接 题意: 机器加工n个木条,每个木条有一个长度和重量.加工第一根木条需要1分钟的准备时间,接下来如果后一根木条的长度和质量都大于等于前一根木条,则不需要准备时间,否则需要1分钟的准备时间,求加工完所有木条最少时间. 比如有5根木条,长度和重量分别是(4,9), (5,2), (2,1), (3,5), (1,4),则需要2分钟就可加工第1分钟加工(1,4), (3,5), (4,9):第2分钟加工 (2,1), (5,2): 思路:将木条按长度从小到大排序,dp[i]记录第i根木条是在什

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较

uva 10003 Cutting Sticks 简单区间dp

// uva 10003 Cutting Sticks 区间dp // 经典的区间dp // dp(i,j)表示切割小木棍i-j所需要的最小花费 // 则状态转移为dp(i,j) = min{dp(i,k) + dp(k,j) + a[j]-a[i]) // 其中k>i && k<j // a[j] - a[i] 为第一刀切割的代价 // a[0] = 0,a[n+1] = L; // dp数组初始化的时候dp[i][i+1]的值为 0,这表示 // 每一段都已经是切割了的,不

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio