题意:

让你输出长度为n的某个序列,然后给你m个变量。

每次给某个数赋值的代价是

假设赋值a=7那么代价是3,因为7的二进制位中有3个1。

要求最后总代价最小。

输出总共要进行操作的次数,和最小代价。

先吐槽下,早期的cf题很多没有官方题解,只找到两篇中文题解...第一篇完全没搞懂大神再说什么。建图的方法是在第二篇中受到启发【虽然也没搞懂大神在说什么】

首先说下这题对我的启示:

1.现在对状态这个词越发有深的理解了,很多题目只要理解了某个抽象意义上的状态,加上他们之间的转换的方式【也有很多人说是序的因素】就基本上可以解决了。

2.费用流的计算方式是一整条路径上权值的总和。一开始建了个傻逼的图,感觉弱爆了。

思路:

这题的状态是这样的,对于每一个需要输出的数字来说,它要输出无非有两种来源,一种是选择之前没有赋值过的变量,另外一种是选择之前已经赋值的变量。问题在于当当前要输出的数字选择的变量是之前已经赋值的变量的时候,花费有两种情况,一种是之前已经赋值过相同的值了,另外一种是赋值不同,这两种情况下的花费是不一样的。对于之前已经打印过的数字来说,它的变量只能向以后的某一次操作转变,【因为如果以后不同的数字使用这个变量的话本身就没有意义了,假如下次使用这个变量是一个相同的数字的话我们认为是后来刚打印的数字的状态这种情况下跟原来是等价的】。

一开始可能存在没有被使用的变量这个时候我们可以贪心,当前有变量没有被使用那么我们使用新的变量就是了,假如之前没有相同的数字。

除了源汇外一共两组点,左边是变量和每个数字,右边是数字。【关键是将数字分成两部分了】然后建图就可以根据上边解释的干了。

#include<bits/stdc++.h>
#define MAXN 800
#define MAXM 80002
#define INF 0x3f3f3f3f
using namespace std;
int cost[],jilu[],aans[];
int zong;
bool vis[MAXN];
struct edge{
edge *next,*op;
int t,c,v;
}ES[MAXM],*V[MAXN];
int N,M,S,T,EC=-;
int demond[MAXN],sp[MAXN],prev[MAXN];
edge *path[MAXN];
void addedge(int a,int b,int v,int c=INF){
//printf("%d %d %d %d\n",a,b,v,c);
edge e1={V[a],,b,c,v},e2={V[b],,a,,-v};
ES[++EC]=e1;V[a]=&ES[EC];
ES[++EC]=e2;V[b]=&ES[EC];
V[a]->op=V[b];V[b]->op=V[a];
}
bool SPFA(){
int u,v;
for(u=S;u<=T;u++){
sp[u]=INF;
}
queue<int>q;
prev[S]=-;
q.push(S);
sp[S]=;
vis[S]=;
while(!q.empty()){
u=q.front();
vis[u]=;
q.pop();
for(edge *k=V[u];k;k=k->next){
v=k->t;
if(k->c>&&sp[u]+k->v<sp[v]){
sp[v]=sp[u]+k->v;
prev[v]=u;
path[v]=k;
if(vis[v]==){
vis[v]=;
q.push(v);
}
}
}
}
return sp[T]!=INF;
}
int argument(){
int i,cost=INF,flow=;
edge *e;
for(i=T;prev[i]!=-;i=prev[i]){
e=path[i];
if(e->c<cost)cost=e->c;
}
for(int i=T;prev[i]!=-;i=prev[i]){
e=path[i];
e->c-=cost;e->op->c+=cost;
flow+=e->v*cost;
}
return flow;
}
int maxcostflow(){
int Flow=;
while(SPFA()){
Flow+=argument();
}
return Flow;
}
int n,m;
void init(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&jilu[i]);
for(int j=;j<;j++){
if((jilu[i]>>j)&)cost[i]++;
}
}
S=;T=n+n+m+;
vector<int>bef;
for(int i=,j=;i<=n&&j<=m;i++){
bool ok=;
for(int k=;k<bef.size();k++){
if(bef[k]==jilu[i]){
ok=;break;
}
}
if(ok){
bef.push_back(jilu[i]);
addedge(j+n,i,cost[i],);
j++;
}
}
for(int i=;i<=n;i++){
addedge(i,T,,);
addedge(S,i+n+m,,);
}
for(int i=n+;i<=n+m;i++){
addedge(S,i,,);
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(jilu[i]==jilu[j])addedge(i+n+m,j,,);
else addedge(i+n+m,j,cost[j],);
}
}
zong=n;
}
int main()
{
init();
int ans=maxcostflow();
for(int i=;i<=n;i++){
for(edge *k=V[i];k;k=k->next){
if(k->t>n){
if(k->v!=&&k->c!=){
zong++;
}
}
}
}
printf("%d %d\n",zong,ans);
for(int i=;i<=n;i++){
for(edge *k=V[i];k;k=k->next){
if(k->c!=){
bool ok=;
if(k->v==)ok=;
if(k->t<=n+m){
printf("%c=%d\n",'a'-+k->t-n,jilu[i]);
printf("print(%c)\n",'a'-+k->t-n);
aans[k->t-n]=jilu[i];
}
else{
for(int j=;j<=m;j++){
if(aans[j]==jilu[k->t-n-m]){
//puts("======");
if(ok)printf("%c=%d\n",'a'-+j,jilu[i]);
printf("print(%c)\n",'a'-+j);
aans[j]=jilu[i];
break;
}
}
}
break;
}
}
}
}

     

Codeforces 132E Bits of merry old England 【最小费用最大流】的更多相关文章

  1. UVA 1658 海军上将(拆点法+最小费用限制流)

    海军上将 紫书P375 这题我觉得有2个难点: 一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点. 二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制 ...

  2. Luogu P3381 (模板题) 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...

  3. Luogu--3381 【模板】最小费用最大流

    题目链接 3381 [模板]最小费用最大流 手写堆版本 dijkstra   400+ms 看来优先队列的常数好大 #include<bits/stdc++.h> using namesp ...

  4. HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]

    题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...

  5. nowcoder 206A - Birthday - [最小费用最大流]

    题目链接:https://www.nowcoder.com/acm/contest/206/A 题目描述 恬恬的生日临近了.宇扬给她准备了一个蛋糕.正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为 ...

  6. HDU 6118 度度熊的交易计划(最小费用最大流)

    Problem Description度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个 ...

  7. TZOJ 4712 Double Shortest Paths(最小费用最大流)

    描述 Alice and Bob are walking in an ancient maze with a lot of caves and one-way passages connecting ...

  8. TZOJ 1513 Farm Tour(最小费用最大流)

    描述 When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 &l ...

  9. 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]

    题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

随机推荐

  1. MongoDB 入门与实例

    一.准备工作 1. 下载mongoDB 下载地址:http://www.mongodb.org/downloads 选择合适你的版本 相关文档:http://www.mongodb.org/displ ...

  2. 取消GridView/ListView item被点击时的效果

    方法一,在控件被初始化的时候设置 ? 1 2 gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); listView.setSelec ...

  3. StringBuilder与StringBuffer的区别(转)

    相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类.St ...

  4. smarty变量

    前台: 注释的两种方式:<{**}>和<!--注释html代码-->比如: <{* <div style="width:100px; height:100 ...

  5. openstack(liberty):部署实验平台(一,基础网络环境搭建)

    openstack项目的研究,到今天,算是要进入真实环境了,要部署实验平台了.不再用devstack了.也就是说,要独立controller,compute,storage和network了.要做这个 ...

  6. HackerRank "Kundu and Tree" !!

    Learnt from here: http://www.cnblogs.com/lautsie/p/3798165.html Idea is: we union all pure black edg ...

  7. HackerRank "AND xor OR"

    Actually I think problem statement is somewhat misleading. No need to mention range [L, R] at all. T ...

  8. 轻量级开源内存数据库SQLite性能测试

    [IT168 专稿]SQLite是一款轻型的数据库,它占用资源非常的低,同时能够跟很多程序语言相结合,但是支持的SQL语句不会逊色于其他开源数据库.它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品 ...

  9. Oracle11g中Exp命令空表不能导出的问题

    http://www.jb51.net/article/43894.htm 一.不能导出空表的原因 1.Oracle11g默认对空表不分配segment,故使用exp导出Oracle11g数据库时,空 ...

  10. linux awk命令

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...