状压DP/01背包


  Orz Gromah

  容易发现m的范围很小……只有16,那么就可以状压,用一个二进制数来表示买了的物品的集合。

  一种简单直接的想法是:令$f[i][j]$表示前$i$个商店买了状态集合为$j$的商品的最小代价,那么我们转移的时候就需要枚举在第$i$个商店买了哪些商品吗,这样的话带上枚举子集,复杂度就会变成$O(n*3^m)$,并不是我们能够忍受的……

  那么怎么搞呢?我们每次转移的时候,不再枚举子集,而是搞一个类似01背包的东西:(以下来自Gromah)

  我们首先令$f[i][j]=f[i-1][j]+d[i]$,表示到达第$i$个商店。

  然后枚举每个状态$j$,以及每个不在$j$里的物品$k$,令:$$f[i][j+\{k\}]=min(f[i][j+\{k\}],f[i][j]+cost[i][k])$$

  这个过程就相当于是进行了一次01背包。

  最后还要令$f[i][j]=min(f[i][j],f[i-1][j])$看看在商店$i$时的购买计划是否划算。

  时间复杂度$O(nm2^m)$,空间复杂度$O(n2^m)$。

 /**************************************************************
Problem: 4145
User: Tunix
Language: C++
Result: Accepted
Time:6948 ms
Memory:29440 kb
****************************************************************/ //BZOJ 4145
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=,v=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
return r*v;
}
const int N=,M=<<,INF=0x3f3f3f3f;
/*******************template********************/ int n,m,f[N][M],d[N],c[N][];
int main(){
#ifndef ONLINE_JUDGE
freopen("4145.in","r",stdin);
freopen("4145.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,,n){
d[i]=getint();
rep(j,m) c[i][j]=getint();
}
rep(j,<<m) f[][j]=INF;
f[][]=;
F(i,,n){
rep(j,<<m) f[i][j]=f[i-][j]+d[i];
rep(j,<<m) rep(k,m){
int s=<<k;
if ((j&s)==) f[i][j^s]=min(f[i][j^s],f[i][j]+c[i][k]);
}
rep(j,<<m) f[i][j]=min(f[i][j],f[i-][j]);
}
printf("%d\n",f[n][(<<m)-]);
return ;
}

4145: [AMPPZ2014]The Prices

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 70  Solved: 47
[Submit][Status][Discuss]

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号物品,在第二家店买剩下的物品。

Source

[Submit][Status][Discuss]

【BZOJ】【4145】【AMPPZ2014】The Prices的更多相关文章

  1. 【BZOJ 2754 喵星球上的点名】

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2512  Solved: 1092[Submit][Status][Discuss] Descript ...

  2. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  3. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  4. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  5. 【BZOJ】【1025】【SCOI2009】游戏

    DP/整数拆分 整个映射关系可以分解成几个循环(置换群的预备知识?),那么总行数就等于各个循环长度的最小公倍数+1(因为有个第一行的1~N).那么有多少种可能的排数就等于问有多少种可能的最小公倍数. ...

  6. 【BZOJ】1013: [JSOI2008]球形空间产生器sphere

    [BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...

  7. 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

  8. 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...

  9. 【BZOJ】【3083】遥远的国度

    树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...

  10. 【BZOJ】【2434】【NOI2011】阿狸的打字机

    AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...

随机推荐

  1. 最受欢迎编程语言又是谁?C语言居首,大数据赢了

    C语言占据榜首,但大数据类是最大赢家. IEEE Spectrum的第三次“最受欢迎编程语言”交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum使用多样化.可交互的的指标权重来 ...

  2. chrome使用技巧(转)

    原文:http://www.cnblogs.com/liyunhua/p/4544738.html 阅读目录 写在前面 快速切换文件 在源代码中搜索 在源代码中快速跳转到指定的行 使用多个插入符进行选 ...

  3. AngularJS过滤器filter入门

    在开发中,经常会遇到这样的场景 如用户的性别分为“男”和“女”,在数据库中保存的值为1和0,用户在查看自己的性别时后端返回的值自然是1或0,前端要转换为“男”或“女”再显示出来: 如我要换个羽毛球拍, ...

  4. Spring 中的事务操作、注解、以及 XML 配置

    事务 事务全称叫数据库事务,是数据库并发控制时的基本单位,它是一个操作集合,这些操作要么不执行,要么都执行,不可分割.例如我们的转账这个业务,就需要进行数据库事务的处理. 转账中至少会涉及到两条 SQ ...

  5. UVA.11427.Expect the Expected(期望)

    题目链接 \(Description\) https://blog.csdn.net/Yukizzz/article/details/52084528 \(Solution\) 首先每一天之间是独立的 ...

  6. [CQOI2009]跳舞

    思路:二分答案+最大流.二分答案$m$,表示最多跳$m$轮.将每个人拆成两个点$a_i$$b_i$,$a_i$表示与任何人跳舞,$b_i$表示与不喜欢的人跳舞.对于第$i$个人,连一条从$a_i$到$ ...

  7. 有向图强连通分量的Tarjan算法和Kosaraju算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  8. centos7 做rails 执行rails server 报错

    做操作rails   server 时  报错 这个错误时因为一些东西没有安装 gem install execjsgem install therubyracersudo apt-get insta ...

  9. Elasticsearch 实现自定义排序插件

    插件入口: package ttd.ugc.plugin; import org.elasticsearch.plugins.Plugin;import org.elasticsearch.scrip ...

  10. Unity3D对安卓盒子的支持

    一般的安卓盒子主要按键包含 1.方向键:上下左右 2.确认 3.返回 4.音量(Unity无法获取),须要在安卓层将事件发上来,KeyCode = 24,25 基本的函数是 if (Input.Get ...