题意

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

\(n \leq 100,m \leq 16\)

分析

状压裸题,看题意和数据范围就能想出用\(f(i,s)\)前\(i\)个商店买了状态\(s\)的最小花费。

然后是状态转移的一点问题,对每个商店枚举子集会超时,需要快速子集和变换类似的方法来内部转移。

方法就是用每个物品松弛一遍,刷表法。

转移的证明

考虑归纳证明。

首先从前一层转移过来本身就是最优的肯定是合法的。

其次每个状态会向后转移,对后面的状态肯定存在一条最优路径,而这种转移隐式包含了这条最优路径。

所以是正确的。

时间复杂度\(O(n m 2 ^m)\)

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
using namespace std;
typedef long long ll; co int MAXN=101,MAXM=16;
int n,m;
int d[MAXN],c[MAXN][MAXM];
int f[MAXN][1<<MAXM]; int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;++i)
{
read(d[i]);
for(int j=0;j<m;++j)
read(c[i][j]);
}
memset(f,0x3f,sizeof f);
f[0][0]=0;
for(int i=1;i<=n;++i)
{
for(int j=0;j<1<<m;++j)
f[i][j]=f[i-1][j]+d[i];
for(int j=0;j<1<<m;++j)
for(int k=0;k<m;++k)
if(~j&(1<<k))
f[i][j|(1<<k)]=min(f[i][j|(1<<k)],f[i][j]+c[i][k]);
for(int j=0;j<1<<m;++j)
f[i][j]=min(f[i][j],f[i-1][j]);
}
printf("%d\n",f[n][(1<<m)-1]);
return 0;
}

BZOJ4145 [AMPPZ2014]The Prices的更多相关文章

  1. bzoj4145 AMPPZ2014 The Prices 状压dp

    这个题.......很可以,很小清晰......反正正经的东西我都没想到:重点在于——————我不会处理那个多出来的路费所以当时我就骚骚的弄了一颗树包状压其实这是一个类01背包的状压在每个状态用01背 ...

  2. bzoj4145 [AMPPZ2014]The Prices(状压dp)

    Description 你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为d[i],在第i家商店购买第j种物品的费用为c[i][j], 求最小总费用. Input 第一行包含两个正整数n, ...

  3. bzoj4145 [AMPPZ2014]The Prices 状压 DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4145 题解 好像这道题有不少方法呢. ...谁叫这道题有点简单,所以方法多呗. 我的方法: 求 ...

  4. 【BZOJ4145】[AMPPZ2014]The Prices 状压DP

    [BZOJ4145][AMPPZ2014]The Prices Description 你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为d[i],在第i家商店购买第j种物品的费用为c[i ...

  5. BZOJ 4145: [AMPPZ2014]The Prices( 状压dp + 01背包 )

    我自己只能想出O( n*3^m )的做法....肯定会T O( nm*2^m )做法: dp( x, s ) 表示考虑了前 x 个商店, 已买的东西的集合为s. 考虑转移 : 先假设我们到第x个商店去 ...

  6. BZOJ.4145.[AMPPZ2014]The Prices(状压DP)

    BZOJ 比较裸的状压DP. 刚开始写麻烦惹... \(f[i][s]\)表示考虑了前\(i\)家商店,所买物品状态为\(s\)的最小花费. 可以写求一遍一定去\(i\)商店的\(f[i]\)(\(f ...

  7. BZOJ 4145 [AMPPZ2014] The Prices 解题报告

    感觉也是一个小清新题.. 我们考虑设立状态 $Dp[i][s]$ 表示考虑了前 $i$ 个商店后,购买状态为 $s$ 的最小花费. 转移的话就枚举每个商店 $i$,首先令: $$Dp[i][s] = ...

  8. [BZOJ] 4145: [AMPPZ2014]The Prices

    设\(f[S][i]\)表示考虑到第\(i\)家店,已经买了集合\(S\)内的物品 一个朴素的想法是枚举子集转移 \[ f[S][i]=\min\{f[T][i-1]+cost[S\oplus T][ ...

  9. bzoj 4145: [AMPPZ2014]The Prices【状压dp】

    设f[s][i]为已经买了集合s,当前在商店i,转移的话就是枚举新买的物品,两种情况,一种是在原商店买,不用付路费,另一种是从其他商店过来,这种再枚举从那个商店过来是不行的,记一个mn[s]为已经买了 ...

随机推荐

  1. PHP stream相关协议及上下文选项和参数归纳

    支持的协议和封装协议 PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen(). copy(). file_exists() 和 filesize() 的文件系统函数. 除了这些封装协 ...

  2. 微信小程序------轮播图

    swiper 微信小程序实现轮播图,和网站,APP的效果差不多,代码少,效率高. 先来看看效果图: 主要用swiper + swiper-item来实现 <view class='swiper' ...

  3. 搞懂分布式技术21:浅谈分布式消息技术 Kafka

    搞懂分布式技术21:浅谈分布式消息技术 Kafka 浅谈分布式消息技术 Kafka 本文主要介绍了这几部分内容: 1基本介绍和架构概览 2kafka事务传输的特点 3kafka的消息存储格式:topi ...

  4. struts.xml路径修改后的web配置

    <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" ...

  5. Quartz教程:快速入门

    原文链接 | 译文链接 | 翻译:nkcoder | 校对:方腾飞 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处 ...

  6. mysql中的tinyint在C#中的类型

    mysql中的tinyint在C#中的类型 在C#中对应的类型是System.SByte,不是byte.

  7. 项目提交到github的忽略文件

    1.在工作区的.gitignore文件中配置如下: # Built application files*.apk*.ap_ # Files for the Dalvik VM*.dex # Java ...

  8. LINUX中文件描述符传递

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  9. Linux服务器通过拷贝的方式安装多个tomcat

    Tomcat占用资源少.运行速度快.安装配置简单,在个人开发中拥有广泛的使用者.很多人在使用中存在以下的误区:1.Tomcat必须通过eclipse启动2.Tomcat必须通过安装才能使用运行3.一台 ...

  10. C++设计模式之-原型模式

    Prototype 模式也正是提供了自我复制的功能, 就是说新对象的创建可以通过已有对象进行创建.在 C++中,拷贝构造函数( Copy Constructor) 曾经是很对程序员的噩梦,浅层拷贝和深 ...