hash——vijos1426 兴奋剂检查

来源:互联网 发布:加工中心简单编程实例 编辑:程序博客网 时间:2024/06/05 19:56

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);}