您的位置:首页 > 其它

hash——vijos1426 兴奋剂检查

2017-05-25 15:50 85 查看
https://vijos.org/p/1426

这个就是一个背包;

但是如果开5维背包的话;

呵呵呵呵呵呵;

那我们就直接把5维hush成一维;

怎么搞?

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


这两种都是可以的;

我们看第一种,展开;

return a*(v[2]+1)*(v[3]+1)*(v[4]+1)*(v[5]+1)+b*(v[3]+1)*(v[4]+1)*(v[5]+1)+c*(v[4]+1)*(v[5]+1)+d*(v[5]+1)+e;


这里怎么理解?

其实很简单的;

我们不能让abcde重复;

我们先放一个e

现在放d*(v[5]+1)

因为v[5]是e的所以的可能性;

所以d*(v[5]+1)就不可能与e重复

同理c*(v[4]+1)(v[5]+1)不会与d(v[5]+1)重复;

因为(v[4]+1)已经包含了d的所有可能;

这是什么?

这个其实就是进制啊;

只不过每一位的进制是不同的而已;

但是他们一定不会重复;

#include<bits/stdc++.h>
using namespace std;
int f[5000002],v[6],a[205][6];
int n,m,ans;
int hush(int a,int b,int c,int d,int e){ return e+(v[5]+1)*(d+(v[4]+1)*(c+(v[3]+1)*(b+(v[2]+1)*a))); return a+(v[1]+1)*(b+(v[2]+1)*(c+(v[3]+1)*(d+(v[4]+1)*e))); }int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d",&v[i]);
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j1=v[1];j1>=a[i][1];j1--)
for(int j2=v[2];j2>=a[i][2];j2--)
for(int j3=v[3];j3>=a[i][3];j3--)
for(int j4=v[4];j4>=a[i][4];j4--)
for(int j5=v[5];j5>=a[i][5];j5--){
int x=hush(j1,j2,j3,j4,j5);
int y=hush(j1-a[i][1],j2-a[i][2],j3-a[i][3],j4-a[i][4],j5-a[i][5]);
f[x]=max(f[x],f[y]+a[i][0]);
ans=max(ans,f[x]);
}
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: