题目描述
对于一个数列{7, 1, 2, 3}进行排序,我们可以把7 从头移动到尾。但是这个操作的成本是7,并不是最佳的。最佳的排序方式是将连续的1、2、3 移动到7 的前面。这样的话,总的操作成本就是1+2+3=6,比之前的成本7 要小。
你的任务是,对于一个给定的数列,输出对这个数列进行排序的最小成本。
输入输出格式
输入格式:
输入文件名为sort.in。
每个输入文件包含多组数据。
输入文件的第一行,包含一个正整数T,代表该输入文件中所含的数据组数。
接下来是T组数据,每组数据的格式如下:
每组数据包含2 行;
第一行包含一个正整数n,代表数列中元素的个数,其中0 < n ≤ 102;
第二行包含n个整数,两个数之间以一个空格隔开,代表数列中的元素ki,其中-10^{7}−107 ≤ ki ≤ 10^{7}107。
输出格式:
输出文件名为sort.out。
输出文件包含T行,分别对应T组数据的答案,即对数列进行排序的最小成本。
输入输出样例
输入样例#1
1 4 7 1 2 3
输出样例#1
6
说明
对于60%的数据:0 < n ≤ 60,-10^{7}−107 ≤ ki ≤ 10^{7}107
对于80%的数据:0 < n ≤ 80, -10^{7}−107 ≤ ki ≤ 10^{7}107
对于100%的数据:0 < n ≤ 102,-10^{7}−107 ≤ ki ≤ 10^{7}107
思路
排序过后的数,一定递增或递减。每次移动某些数字,使得数组递增或递减,而花费是移动数字的和。
排序的是最小成本,那么没有被排序的数,就是排过序的数以外的,就是最大成本了。不妨我们求出每次需要进行排序的2个数中最大的值加上每一次排序用的成本。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int a[101],n,t,s,cnt,b[101];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
register int i,j,k;
cin>>t;
while(t--)
{
s=cnt=0;
memset(b,0,sizeof(b));
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
s=s+a[i];//求数字之和
}
for(i=1;i<=n;i++)
{
for(j=1;j<=i-1;j++)
{
if(a[i]>=a[j])
{
b[i]=max(b[i],b[j]);
}
}
b[i]=b[i]+a[i];
if(b[i]>cnt)
{
cnt=b[j];
}
}
cout<<s-cnt<<endl;
}
return 0;
}