POJ 3270 置换群问题
题目大意是:
每头牛都有一个对应的值a[i],现在给定一个初始的牛的序列,希望通过两两交换,能够使这些牛按值升序排列,每次交换都会耗费一个 a[i]+a[j]
希望耗费最小,求出这个最小耗费
个人觉得这道题还是蛮有意思的,虽然我wa了很多发,但还是很值得思考一下的
这是一个置换群问题,但是我们首先要根据其值排个序确定每头牛本来应该属于的位置,再根据现在所在的位置得到一个映射关系to[i]
将a[i]又用b[]数组保存,排序后,b[i]表示第i大的牛的值
我们找出这个置换群中的所有循环集,每个循环集分别讨论,我们总是找到循环集中值最小的牛占据了别的牛的位置pos,然后把这个pos这个位置交换给对应的牛
这样得到的是b[min]+b[pos],因为每头牛总要回到自己的位置上,假定循环集中有len个牛,那么所有牛都回到自己的位置上那么所有的b[i]都要加一遍
但加的过程希望尽可能的小,所以总是跟b[min]相加,这个是可以保证的,因为在一个循环集中,每次交换最多只能令一个数回到正确位置上,除非到了最后一步
,否则的话,如果同时回到了正确位置,那么这两个数可以独立出来作为一个循环集,这与它们在原来的循环集中是矛盾的
其实到了这里感觉总的思路已经是对的
但是自己就是在这里wa了
想了半天发现还有更优的情况
另外还有一种情况需要考虑就是这个循环集中位置的交换可以利用b[1](也就是最小的牛)来帮忙
是不是通过利用最小编号的牛帮助这个循环集排好队是不是结果更小
最小的牛加进来帮忙就是值为b[1]的牛和当前循环集内最小的牛交换一次位置,帮好忙后再交换回来
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = ;
const int M = ;
int a[N] , b[N] , to[N] , vis[N] , id[M];//to[]记录置换群上的映射关系 int circle(int u)
{
int v = u , ans = ;
int cnt = ;
while(u != to[v]){
vis[v] = ;
cnt++;
ans = ans+b[v];
v = to[v];
}
ans = ans+b[v] , cnt++;
vis[v] = ;
if(cnt == ) return ;
else{
/*这里要判断一下,是不是通过利用最小编号的牛帮助这个循环集排好队是不是结果更小
最小的牛加进来帮忙就是值为b[1]的牛和当前循环集内最小的牛交换一次位置,帮好忙后
再交换回来*/
int tmp = ans + b[u] + (cnt+)*b[];
return min(tmp , ans + (cnt-)*b[u]);
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int n;
while(scanf("%d" , &n) != EOF)
{
for(int i= ; i<=n ; i++)
{
scanf("%d" , a+i);
b[i] = a[i];
}
sort(b+ , b+n+);
for(int i= ; i<=n ; i++)
id[b[i]] = i;
for(int i= ; i<=n ; i++)
to[i] = id[a[i]]; //表示第i个位置被第id[a[i]]大的牛占据了
memset(vis , , sizeof(vis));
int ans = ;
for(int i= ; i<=n ; i++)
if(!vis[i]) ans += circle(i); printf("%d\n" , ans);
}
return ;
}
POJ 3270 置换群问题的更多相关文章
- poj 3270(置换群+贪心)
Cow Sorting Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6993 Accepted: 2754 Descr ...
- poj 3270(置换群)
题意:给定n头母牛的脾气大小,然后让你通过交换任意两头母牛的位置使得最后的母牛序列的脾气值从小到大,交换两头母牛的代价是两个脾气之和,使得代价最小. 分析:以前做过一道题,只有一个地方和这道题不同,但 ...
- POJ 3270 Cow Sorting(置换群)
题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...
- POJ 3270 Cow Sorting(置换群)
题目链接 很早之前就看过这题,思路题把,确实挺难想的,黑书248页有讲解. #include <cstdio> #include <cstring> #include < ...
- Cow Sorting POJ 3270 & HDU 2838
题目网址:http://poj.org/problem?id=3270 题目大意是:一串无序的数字,要排成增序的数列,可以交换不相邻的数,每交换两个数,sum+这两个数,使得sum最小,求最小的sum ...
- poj 3270 Cow Sorting
思路:仔细读题,看到FARMER是两两交换牛的顺序进行排序的话,应该就往置换上靠拢,而这个题果然是置换的应用(有的解题报告上说是置换群,其实这只是单个置换,不用让它构成群).我们来将这些无序的牛抽象成 ...
- poj 1026(置换群)
题意:给你一个变换规则,和一个字符串,问经过k次变换后得到的字符串. 思路:开始的时候试图去找它的整个周期,谁知道周期太大了,各种RE,后来在得知此题需要用置换群来优化,第一次接触置换群学习了下! 代 ...
- poj 3270 置换
poj 置换的应用 黑书原题P248 /** 题意: 给定序列, 将其按升序排列, 每次交换的代价是两个数之和, 问代价最小是多少 思路:1.对于同一个循环节之内的,肯定是最小的与别的交换代价最小 2 ...
- poj 3270 更换使用
1.确定初始和目标状态. 明确.目标状态的排序状态. 2.得出置换群,.比如,数字是8 4 5 3 2 7,目标状态是2 3 4 5 7 8.能写为两个循环:(8 2 7)(4 3 5). 3.观察当 ...
随机推荐
- 10.12NOIP模拟题(2)
/* 有谁知道这道题结论是怎么来的? 晚上问问学数学的孩子23333 */ #include<iostream> #include<cstdio> #include<cs ...
- GG_DataAccess 数据库访问层使用dapper操作
3.5.GG_DataAccess 数据库访问层使用dapper操作 和Model实体类同理,tt模板已写好,需要的可加qq群:547765059 自己下载.
- MongoDB Built-In Roles(内置角色)
1. 数据库用户角色:read.readWrite; 2. 数据库管理角色:dbAdmin.dbOwner.userAdmin: 3. 集群管理角色:clusterAdmin.clusterManag ...
- Hadoop Hive概念学习系列之hive的索引及案例(八)
hive里的索引是什么? 索引是标准的数据库技术,hive 0.7版本之后支持索引.Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某 ...
- Windows下重置MySQL密码【MYSQL】
使用环境:win10 x64企业版 关闭正在运行的MySQL服务. 打开DOS窗口,转到mysqlbin目录. 输入mysqld --skip-grant-tables回车.如果没有出现提示信息,那就 ...
- 2017-12-01HTML块及引用
HTML块1.HTML块元素 快元素在显示时,通常会以新行开始 例如:<h1>.<p>.<ul>2.HTML内联元素 内联元素通常不会以新行开始 例如:<b& ...
- PHP开发心得三
1, JSON在调用json_decode前要检查其中是否含有反斜杠“\”等特殊字符 比如下面这段代码,返回的就是空值,非常坑爹吧. $res = {"Ret":"1&q ...
- java读取03、07版EXCEL
03版excel,需要用到jxl.jar这个jar包 package test.poi; import java.io.File; import java.io.IOException; import ...
- EF 迁移操作
一. 模型设计 1. 遵循EF标准,注意表关系配对 2. 数据模型里尽量把必须的属性和说明都写全 3. EF默认id字段为主键,如果没有,需指定主键 二. 数据迁移 1. 命令运行环境:vis ...
- mysql 性能优化索引、缓存、分表、分布式实现方式。
系统针对5000台终端测试结果 索引 目标:优化查询速度3秒以内 需要优化.尽量避免使用select * 来查询对象.使用到哪些属性值就查询出哪些使用即可 首页页面: 设备-组织查询 优化 避免使用s ...