Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 4746 | Accepted: 1730 |
Description
Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage FJ's milking equipment, FJ would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (not necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes FJ a total of X+Y units of time to exchange two cows whose grumpiness levels are X and Y.
Please help FJ calculate the minimal time required to reorder the cows.
Input
Output
Sample Input
3 2 3 1
Sample Output
7
Hint
Source
USACO 2007 February Gold
题意:就是给你n个数,让你按升序排序,你可以交换任意两个数,但是每次交换的代价是这两个数的和,必须使得代价最小。
这是一道置换的题,一遍过了~~~不过代码写的不够好。
思路:初始状态就是给的状态,目标状态自然是排成升序的状态,把初始状态的下标存到一个数组里,把排序后的下标存到另一个数组里,这样就便于查找循环。
样例中的初始状态是 2 3 1,那么形成的下标数组是1 2 3,最终状态是1 2 3,那么形成的下标数组是3 1 2.
1 2 3
3 1 2
这个置换对应的循环是(1 3 2),只有一个循环节,交换的代价是1+3=4 1+2=3总代价是7
很明显我们是用(1 3 2)这个循环里的最小的数去和其他的数交换,这样能使最后的代价最小,并且一个循环的交换次数是k-1次,k 是这个循环包含的数的个数。
但是这种考虑的方法不一定是最优的,样例中只有一个循环节,若有多个循环节,我们可以用别的循环里的比这个循环里的所有的数小的数来和这个循环里的数来交换,付出的代价不一定比先前那种思路大,所以第二方面我们要考虑把所有数中最小的数与各个循环里最小的数交换,然后与前面那种思路付出的代价比较,取较小的那个。
#include
#include
#include
#include
using namespace std;
int a[10010];
int c[10010];
struct Node
{
int id;
int num;
}node[10010];
int cmp(Node a,Node b)
{
return a.num