codeforces round# 302 (div1 C) (状压dp)
来源:互联网 发布:js undefined判断 编辑:程序博客网 时间:2024/05/22 16:41
本题目的意思是给定n(n<=20)行长度都为过m(m<=20)的字符串,并且给定一个n*m的数字矩阵,cost(i,j)为将第i行第j个字母修改成任意字母的代价。
求用最小的代价让所有的字符串,都存在一个位置,在同列中没有和它相同的字符。
考虑d[ s ]代表状态s下(其中1代表该位置已经唯一,0反之)还需的最小代价,
转移只有两种,找到最小的没被唯一化得位置p, 枚举修改位置j, 可以 (1)修改j本身 或者 ( 2 ) 将j列里所有与该位置第j列有相同字符的修改费用加起来减去一个最大值。
因为左右的可行性转移只有这两种;
还有一个问题 , 比如 n = 4, m = 4, 其中 字符 s[ 1 ][ 3 ] = s[ 2 ][ 3 ] = s[ 3 ][ 3 ]; 那么如果直接修改1,3将第一行唯一化,到后面,决策3时采用了(2 ),那么导致唯一化1的费用可能被计算两边,这个问题不需要担心,因为有比他更优且不产生矛盾的解存在,且同过这种转移可以计算到。
//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <set>#include <map>#include <string>#include <list>#include <cstdlib>#include <queue>#include <stack>#include <cmath>#include <bitset>#include <cassert>#define ALL(a) a.begin(), a.end()#define clr(a, x) memset(a, x, sizeof a)#define fst first#define snd second#define pb push_back#define lowbit(x) (x&(-x))#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define rep1(i,x,y) for(int i=x;i<=y;i++)#define rep(i,n) for(int i=0;i<(int)n;i++)using namespace std;const double eps = 1e-10;typedef long long LL;typedef long long ll;typedef pair<int, int> pii;const int oo =0x3f3f3f3f;const int N = 25;char s[N][N];int cost[N][N],sum[N][N],mask[N][N];int n,m;int d[1<<20];int main(){ scanf("%d %d",&n,&m); rep(i,n) scanf("%s",s[i]); rep(i,n) rep(j,m) scanf("%d",&cost[i][j]); rep(i,n) rep(j,m){ int max_ = 0; sum[i][j] = mask[i][j] = 0; rep(k,n)if(s[i][j] == s[k][j]){ sum[i][j]+=cost[k][j]; mask[i][j]|=(1<<k); max_=max(max_,cost[k][j]); } sum[i][j]-=max_; } int lim = (1<<n)-1; d[lim] = 0; for(int s=lim-1;s>=0;s--){ d[s] = oo; int p = 0; while(p <n-1 && s&(1<<p)) p++; for(int i=0;i<m;i++){ d[s] = min(d[s] , d[s|(1<<p)]+cost[p][i]); d[s] = min(d[s] , d[s|mask[p][i]]+sum[p][i]); } } cout<<d[0]<<endl; return 0;}
0 0
- codeforces round# 302 (div1 C) (状压dp)
- [状压DP] Codeforces Beta Round #72 Div1 E Two Subsequences
- Codeforces Round #125 div1 C Delivering Carcinogen
- Codeforces Round #253 DIV1 C 贪心
- codeforces round# 320 div1(C 思路三分)
- Codeforces Round #445 Div1 C:Maximum Element (组合数学+DP)
- codeforces round# 302 (div1 D 树形计数)
- codeforces round 156 div1
- Codeforces Round #223 div1
- codeforces round #250 div1
- codeforces round #253 div1
- Codeforces Round 313(div1)
- [杂题] Codeforces 830C Round #424 Div1 C. Bamboo Partition
- Codeforces Round #319 (Div. 1) div1 A B C
- Codeforces Round #352 div1 C D (智商+线段树)
- Codeforces Round #441 Div1 C:National Property (2-SAT)
- codeforces round 176Div1 B
- Codeforces Round #228 div1前三题
- hdu 2082 找单词 母函数
- 关于swt 和一些小技巧
- Chapter 7 String to Integer
- LeetCode 7 反转数字
- jdk的配置与测试
- codeforces round# 302 (div1 C) (状压dp)
- 数据库Sharding的基本思想和切分策略
- 局域网中其他电脑访问我的电脑上的apache服务器
- 读取单个图片
- TopCoder SRM 667 Div1 Problem 250 - OrderOfOperations (状压dp)
- 自定义ListView实现仿QQ消息列表滑动item出现删除按钮
- SQL语法优化
- iOS 开发中关于时间显示问题(今天/昨天/前天/星期几/具体日期)
- 正确理解ThreadLocal