zoukankan      html  css  js  c++  java
  • BZOJ 4145 [AMPPZ2014]The Prices (状压DP)

    一般的思路是(dp[i][j])代表前i个商店购买集合为j的最小费用,枚举每一个商店然后枚举子集。复杂度(O(n3^m))过不了。
    先把(dp[i][j])设为(dp[i-1][j])表示钦定在这个商店购物,然后在(dp[i])中做背包。
    具体就是枚举每一个商品买不买。
    然后惊奇的发现这样复杂度为(O(nm2^m))可以通过本题。

    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int N=70000;
    int n,m,d[110],c[110][20],dp[2][N];
    int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    	return sum*f;
    }
    int main(){
    	n=read();m=read();
    	for(int i=1;i<=n;i++){
    		d[i]=read();
    		for(int j=1;j<=m;j++)
    			c[i][j]=read();
    	}
    	memset(dp,0x3f,sizeof(dp));
    	dp[0][0]=0;
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<(1<<m);j++)
    			dp[i&1][j]=dp[(i&1)^1][j]+d[i];
    		for(int j=1;j<=m;j++)
    			for(int k=1;k<(1<<m);++k)
    				if(k&(1<<j-1))
    					dp[i&1][k]=min(dp[i&1][k],dp[i&1][k^(1<<j-1)]+c[i][j]);
    		for(int j=0;j<(1<<m);j++)
    			dp[i&1][j]=min(dp[i&1][j],dp[(i&1)^1][j]);
    	}
    	printf("%d
    ",dp[n&1][(1<<m)-1]);
    	return 0;
    }
    
  • 相关阅读:
    spoj694 DISUBSTR
    poj3261 Milk Patterns
    poj1743 Musical Theme
    Hdu1403 Longest Common Substring
    bzoj3779 重组病毒
    bzoj3083 遥远的国度
    bzoj3514 Codechef MARCH14 GERALD07加强版
    PAT 乙级 1027 打印沙漏(20) C++版
    PAT 乙级 1060 爱丁顿数(25) C++版
    windows编程之窗口抖动
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/10468802.html
Copyright © 2011-2022 走看看