您的位置:首页 > 其它

Vijos 1426 兴奋剂的检验

2016-08-02 18:12 197 查看

背景

北京奥运会开幕了,这是中国人的骄傲和自豪,中国健儿在运动场上已经创造了一个又一个辉煌,super pig也不例外………………

描述

虽然兴奋剂是奥运会及其他重要比赛的禁药,是禁止服用的。但是运动员为了提高成绩难免要服用一些,super pig也不例外。为了不被尿检检查出来,这些药品就只能选一些不容易被发现的来服用。但是奥委会关于兴奋剂检查有很多个指标,只有尿检中各项数值均不高于规定指标才算成阴性(“你没服兴奋剂”),所以如何服用适量的药品使自己的水平达到最高是每个运动员困扰的问题。

现在有n个药品,每个药品如服用就必须全部用掉(否则会有副作用)。尿检检查共有m个项目,服用每个药品对于每个检查项目都会得到一定的效果值,这些效果值是累加的;服用每个药品当然还会给super pig一些水平提高值,这些效果也是累加的。现在super pig想把问题交给你来解决,因为吃药归吃药,训练才重要。

格式

输入格式

第一行有两个整数n (0

输出格式

一个整数,即super pig通过服这些药在不被检查出来的条件下所能得到的最高水平提高值

样例1

样例输入

5 1

6

7 3

8 5

3 1

6 2

4 3

样例输出

16

限制

各个测试点1s

如果一般思路来说,要开一个f[i][a][b][c][d][e]的六维数组,但是从

数据来看,一定会爆,所以我们可以用hash优化,其实题目中也有提示,

从数据范围可以看出。

v的累乘值不超过5000000,所以开一个数组f[5000000]就可以了,

hash函数用

int hash(int a,int b,int c,int d,int e) {
return a*(s[2]+1)*(s[3]+1)*(s[4]+1)*(s[5]+1)+b*(s[3]+1)*
(s[4]+1)*(s[5]+1)+c*(s[4]+1)*(s[5]+1)+d*(s[5]+1)+e;
}


来判断,一般不会重复。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#define M 5000001
#define N 220
using namespace std;
int f[M];
int s
,v
[6],w
;
int n,m;
int read() {
int x=0;char c=getchar();
while(c>'9'||c<'0') c=getchar();
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x;
}
int hash(int a,int b,int c,int d,int e) { return a*(s[2]+1)*(s[3]+1)*(s[4]+1)*(s[5]+1)+b*(s[3]+1)* (s[4]+1)*(s[5]+1)+c*(s[4]+1)*(s[5]+1)+d*(s[5]+1)+e; }
void go() {
for(int i=1;i<=n;i++)
for(int j=s[1];j>=v[i][1];j--)
for(int k=s[2];k>=v[i][2];k--)
for(int l=s[3];l>=v[i][3];l--)
for(int p=s[4];p>=v[i][4];p--)
for(int t=s[5];t>=v[i][5];t--) {
int x=hash(j,k,l,p,t);
f[x]=max(f[x],f[hash(j-v[i][1],k-v[i][2],l-v[i][3],p-v[i][4],t-v[i][5])]+w[i]);
}
printf("%d",f[hash(s[1],s[2],s[3],s[4],s[5])]);
return;
}
int hh() {
system("color 6e");
n=read();m=read();
for(int i=1;i<=m;i++) s[i]=read();
for(int i=1;i<=n;i++) {
w[i]=read();
for(int j=1;j<=m;j++)
v[i][j]=read();
}
go();
return 0;
}
int hhh=hh();
int main(){;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vijos