zoukankan      html  css  js  c++  java
  • 【BZOJ4145】[AMPPZ2014]The Prices 状压DP

    【BZOJ4145】[AMPPZ2014]The Prices

    Description

    你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为d[i],在第i家商店购买第j种物品的费用为c[i][j],
    求最小总费用。

    Input

    第一行包含两个正整数n,m(1<=n<=100,1<=m<=16),表示商店数和物品数。
    接下来n行,每行第一个正整数d[i](1<=d[i]<=1000000)表示到第i家商店的路费,接下来m个正整数,
    依次表示c[i][j](1<=c[i][j]<=1000000)。

    Output

    一个正整数,即最小总费用。

    Sample Input

    3 4
    5 7 3 7 9
    2 1 20 3 2
    8 1 20 1 1

    Sample Output

    16

    HINT

    在第一家店买2号物品,在第二家店买剩下的物品。

    题解:看到数据范围先想到费用流,发现费用流写不出来只好改写状压

    设当前枚举到第i个商店,用f[k]表示逛了第i个商店,所买物品状态为j的最小花费,用g[k]表示在前i个商店中,所买物品状态为j的最小花费,然后慢慢转移吧~

    时间复杂度O(nm*2^m)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    int n,m;
    int c[110][20],d[110],f[1<<16],g[1<<16];
    int min(int x,int y,int z)
    {
    	return min(min(x,y),z);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int i,j,k;
    	for(i=1;i<=n;i++)
    	{
    		scanf("%d",&d[i]);
    		for(j=1;j<=m;j++)	scanf("%d",&c[i][j]);
    	}
    	memset(g,0x3f,sizeof(g));
    	g[0]=0;
    	for(i=1;i<=n;i++)
    	{
    		memset(f,0x3f,sizeof(f));
    		f[0]=d[i];
    		for(k=1;k<(1<<m);k++)
    		{
    			for(j=1;j<=m;j++)
    			{
    				if(k&(1<<j-1))
    				f[k]=min(f[k],g[k^(1<<j-1)]+d[i]+c[i][j],f[k^(1<<j-1)]+c[i][j]);
    			}
    			g[k]=min(g[k],f[k]);
    		}
    	}
    	printf("%d",g[(1<<m)-1]);
    	return 0;
    }
  • 相关阅读:
    Java EE部分-- 各框架对比与项目优化
    Java EE部分--Mybatis
    Java EE部分--MVC
    Java EE部分--Hibernate、Struts
    Java EE部分--spring(二)
    Java EE部分--spring(一)
    IO和NIOAIO
    JDK、 反射

    线程(二)
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6830269.html
Copyright © 2011-2022 走看看