BZOJ-4145: [AMPPZ2014]The Prices

[文章目录]

Description

你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为di,在第i家商店购买第j种物品的费用为cij,求最小总费用。1<=n<=100,1<=m<=16

状压DP,枚举子集。
将物品状态压缩,求出每个状态在每个商店购买价钱的最小值,发现答案是由一些子状态的并集构成。对每个状态枚举子集即可。时间复杂度O(n*2^m+3^m)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define R register
using namespace std;
int w[(1<<16)+64],dp[(1<<16)+64];
inline int Min(int x,int y){return x<y?x:y;}
int main()
{
    int n,m; scanf("%d%d",&n,&m);
    memset(dp,0x3f,sizeof(int)*((1<<m)+10));
    int now,lim=(1<<m); dp[0]=0;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&now);
        for(int j=0;j!=m;++j) scanf("%d",w+(1<<j));
        for(R int s=1;s!=lim;++s)
        {
            w[s]=w[s-(-s&s)]+w[-s&s];
            dp[s]=Min(dp[s],w[s]+now);
        }
    }
    R int s1,s2;
    for(s1=1;s1!=lim;++s1)
        for(s2=s1;s2;s2=s1&(s2-1))
            dp[s1]=Min(dp[s1],dp[s2]+dp[s1^s2]);
    printf("%d",dp[lim-1]);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注