您的位置:首页 > 其它

[Swust OJ 838]--最优价值(0-1背包+数学)

2015-06-28 00:52 302 查看
题目链接:http://acm.swust.edu.cn/problem/838/

Time limit(ms): 1000        Memory limit(kb): 10000

Description

我们定义了这个一个函数:

void Judge(int x, int &A, int &B, int &C)
{
int i;
for (A = 2; A<x; A++)
if (x%A == 0)
{
B = x / A;
break;
}
C = 0;
for (i = 1; i <= x; i++)
if (x%i == 0)
C++;
}


对于每一个非素数X可以通过Judge函数得到A,B,C三个数。X的价值就定义为V=(A^B)%C

对于素数Y的价值V定义为:V=Y%10

现在给你一个大于1的正整数N,那么你将会有一个区间[2,N],现在你的问题是从中选择若干个互不相同的数,使其和不大于给定的另一个数S。同时使这些互不相等的数的价值总和最大。所以问题就是给定N和S,求出满足上诉条件的最大总价值。

Input

输入两个数N,S.(2<=N<=20000,2<=S<=60000)

Output

输出最大的总价值。

Sample Input

3 3
Sample Output

3
解题思路:一个有意思的题,考了不少知识点,就相当于给定一个区间的数,找出它们的权值,然后转换为一个0-1背包问题,大致思路如下
     (1)对于a,b,c的值按照给出代码直接模拟求就是了(注意稍稍来点优化,一开始超时了Orz~~~)
     (2)判断一个数是否为素数,打表
     (3)求非素数的价值二分快速幂高精度取模
     (4)求最大总价值0-1背包

代码如下:

//背包,素数表,高精度取模
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;

#define maxn 60005
typedef long long LL;
LL wi[maxn], vi[maxn], dp[maxn], n, s;
LL prime[maxn] = { 1, 1, 0 };

void Prime(){
for (int i = 2; i <= maxn; i++){
if (!prime[i]){
for (int j = 2; i*j <= maxn; j++)
prime[i*j] = 1;
}
}
}

LL mulit_mod(LL a, LL b, LL c){
LL t = 1;
while (b){
if (b & 1) t = a*t % c;
b >>= 1;
a = a*a % c;
}
return t;
}

LL judge(LL x){
LL a, b, vi, t = (LL)sqrt((double)x);
if (!(x & 1)){
a = 2;
b = x / 2;
}
else{
for (a = 2; a <= t; a++){
if (x%a == 0){
b = x / a;
break;
}
}
}
vi = 0;
//优化一下,否则超时
//for (LL i = 1; i <= x; i++){
//  if (!(x%i)) vi++;
//}
for (LL i = 1; i <= t; i++){
if (!(x%i)){
LL e = x / i;
if (e > i) vi += 2;
else if (e == i)
vi += 1;
}
}
return mulit_mod(a, b, vi);
}

void init(){
Prime();
for (LL i = 2; i < maxn; i++){
wi[i] = i;
if (prime[i]) vi[i] = judge(i);
else vi[i] = i % 10;
}
}

int main(){
init();
while (~scanf("%lld%lld", &n, &s)){
memset(dp, 0, sizeof(dp));
for (LL i = 2; i <= n; i++){
for (LL j = s; j >= wi[i]; j--)
dp[j] = max(dp[j], dp[j - wi[i]] + vi[i]);
}
printf("%lld\n", dp[s]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: