Hdu 2015 Multi-University Training Contest10

还是善始善终一点吧。
整整被虐了十场比赛。

1002

题面

Problem Description
CRB has N different candies. He is going to eat K candies.
He wonders how many combinations he can select.
Can you answer his question for all K(0 ≤ K ≤ N)?
CRB is too hungry to check all of your answers one by one, so he only asks least common multiple(LCM) of all answers.

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case there is one line containing a single integer N.
1 ≤ T ≤ 300
1 ≤ N ≤ 106

Output
For each test case, output a single integer – LCM modulo 1000000007(109+7).

Sample Input

5
1
2
3
4
5

Sample Output

1
2
3
12
10

题意

求杨辉三角形每一行所有数的lcm是多少。

解析

转换成求 lcm(1,2,3...,n)/n
这题麻烦的是lcm…非常大,所以只能在中间过程取模最后的除法是不满足取模运算的。
所以,有一个计算的方法:
(a/b)%m ,当 gcd(b,m)=1 时可以转换为 (ainv(b))%m ,而题中mod恰好为一个素数。
然后求lcm(1,2,3,…,n)的方法是网上找的,可以求到1e8的n。

然后我一直wa。。。找各种原因,然后想放弃这题了,跪了。
新开了一个文件准备写其他题,然后忽然想起,我是不是文件没关。。。
最后。。。
呵呵

代码

#pragma comment(linker, "/STACK:1677721600")
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <algorithm>
#define pb push_back
#define mp make_pair
#define LL long long
#define lson lo,mi,rt<<1
#define rson mi+1,hi,rt<<1|1
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i,a,b) for(int i=(a); i<=(b); i++)
#define dec(i,a,b) for(int i=(a); i>=(b); i--)

using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;

const int N = 1000000+2;
const ll MOD = 1e9 + 7;

unsigned int vis[(N+31)/32 + 5];
int pri[5770000], pnum;
unsigned int sum[5770000];

bool Get(int i)
{
    int x = i/32, y = i%32;
    return 1<<y & vis[x];
}

void Set(int i)
{
    int x = i/32, y = i%32;
    vis[x] |= 1<<y;
}

void get_prime(int n)
{
    pnum = 0;
    for(int i = 2; i <= n; i++)
    {
        if(!Get(i)) pri[pnum++] = i;
        for(int j = 0; j < pnum; j++)
        {
            if(i*pri[j] > n)    break;
            Set(i*pri[j]);
            if(i%pri[j] == 0)   break;
        }
    }
    sum[0] = pri[0];
    for(int i = 1; i < pnum; i++)    sum[i] = (ll)sum[i-1]*pri[i]%MOD;
}

int n;

bool ok(int cnt, int m)
{
    ll now = 1;
    for(int i = 0; i < cnt; i++)
    {
        now *= pri[m];
        if(now > n) return false;
    }
    return true;
}

int bin(int cnt)
{
    int l = 0, r = pnum-1, ret = -1;
    while(l <= r)
    {
        int mid = l+r>>1;
        ll now = 1;
        if(ok(cnt, mid))
        {
            ret = mid;
            l = mid+1;
        }
        else
            r = mid-1;
    }
    return ret;
}

void ex_gcd(ll a, ll b, ll& x, ll& y)
{
    if(!b)
    {
        x = 1;
        y = 0;
    }
    else
    {
        ex_gcd(b, a % b, y, x);
        y -= x*(a/b);
    }
}

//ax=1 mod(m) 返回x
ll inv(ll a, ll m)
{
    ll x, y;
    ex_gcd(a, m, x, y);
    return (x % m + m) % m;
}

int main()
{
    ///FIN;
    get_prime(1000001);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        n++;
        ll ans = 1;
        int cur = 1;
        while(true)
        {
            int ret = bin(cur);
            if(ret == -1)   break;
            ans = (ll)ans*sum[ret]%MOD;
            cur++;
        }
        printf("%u\n", (ans * inv(n, MOD))%MOD);
    }
    return 0;
}

1005

题面

Problem Description
Today is CRB’s birthday. His mom decided to buy many presents for her lovely son.
She went to the nearest shop with M Won(currency unit).
At the shop, there are N kinds of presents.
It costs Wi Won to buy one present of i-th kind. (So it costs k × Wi Won to buy k of them.)
But as the counter of the shop is her friend, the counter will give Ai × x + Bi candies if she buys x(x>0) presents of i-th kind.
She wants to receive maximum candies. Your task is to help her.
1 ≤ T ≤ 20
1 ≤ M ≤ 2000
1 ≤ N ≤ 1000
0 ≤ Ai, Bi ≤ 2000
1 ≤ Wi ≤ 2000

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers M and N.
Then N lines follow, i-th line contains three space separated integers Wi, Ai and Bi.

Output
For each test case, output the maximum candies she can gain.

Sample Input

1
100 2
10 2 1
20 1 1

Sample Output

21
Hint
CRB’s mom buys 10 presents of first kind, and receives 2 × 10 + 1 = 21 candies.

题意

拿糖果,你有容量为m的背包,有n个糖果,每颗糖果的体积为w,拿x颗糖果的价值为ax+b。问如何拿糖果使得价值最大。

解析

01背包+完全背包。

代码

#pragma comment(linker, "/STACK:1677721600")
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <algorithm>
#define pb push_back
#define mp make_pair
#define LL long long
#define lson lo,mi,rt<<1
#define rson mi+1,hi,rt<<1|1
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i,a,b) for(int i=(a); i<=(b); i++)
#define dec(i,a,b) for(int i=(a); i>=(b); i--)

using namespace std;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double ee = exp(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 20000 + 10;
const int maxv = 20000 + 10;
const double pi = acos(-1.0);
const LL iinf = 0x3f3f3f3f3f3f3f3f;

int packV;
int dp[maxv];
int cost[maxn];
int value[maxn];

// for (int i = 1; i <= n; i++)
//  zeroOnePack(c[i], w[i]);
void zeroOnePack(int cost, int weight)
{
    for (int v = packV; v >= cost; v--)
    {
        dp[v] = Max(dp[v], dp[v - cost] + weight);
    }
}
// for (int i = 1; i <= n; i++)
//  completePack(c[i], w[i]);
void completePack(int cost, int weight)
{
    for (int v = cost; v <= packV; v++)
    {
        dp[v] = Max(dp[v], dp[v - cost] + weight);
    }
}

int readT()
{
    char c;
    int ret = 0,flg = 0;
    while(c = getchar(), (c < '0' || c > '9') && c != '-');
    if(c == '-') flg = 1;
    else ret = c ^ 48;
    while( c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c ^ 48);
    return flg ? - ret : ret;
}

int main()
{
#ifdef LOCAL
    FIN;
#endif // LOCAL
    int ncase = readT();
    while (ncase--)
    {
        int n;
        scanf("%d%d", &packV, &n);
        rep(i, 1, n)
        {
            cost[i] = readT();
            cost[i + n] = cost[i];
            int A = readT();
            int B = readT();
            value[i] = A + B;
            value[i + n] = A;
        }
        mem(dp, 0);
        rep(i, 1, n)
        {
            zeroOnePack(cost[i], value[i]);
        }
        rep(i, n + 1, n * 2)
        {
            completePack(cost[i], value[i]);
        }
        printf("%d\n", dp[packV]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值