题
There are n armchairs, numbered from 1 to n from left to right. Some armchairs are occupied by people (at most one person per armchair), others are not. The number of occupied armchairs is not greater than n/2.
For some reason, you would like to tell people to move from their armchairs to some other ones. If the i-th armchair is occupied by someone and the j-th armchair is not, you can tell the person sitting in the i-th armchair to move to the j-th armchair. The time it takes a person to move from the i-th armchair to the jj-th one is |i - j|minutes. You may perform this operation any number of times, but these operations must be done sequentially, i. e. you cannot tell a person to move until the person you asked to move in the last operation has finished moving to their destination armchair.
You want to achieve the following situation: every seat that was initially occupied must be free. What is the minimum time you need to do it?
Input
The first line contains one integer nn (2≤n≤5000) — the number of armchairs.
The second line contains n integers a1, a2, ……, an(0≤ai ≤1).
ai=1 means that the ii-th armchair is initially occupied, ai = 0means that it is initially free. The number of occupied armchairs is at most n/2.
Output
Print one integer — the minimum number of minutes you have to spend to achieve the following situation: every seat that was initially occupied must be free.
Sample 1
Input
7
1 0 0 1 0 0 1
Output
3
Sample 2
Input
6
1 1 1 0 0 0
Output
9
Sample 3
Input
5
0 0 0 0 0
Output
0
题意
有一排椅子,其中有n/2的椅子有人坐(值为1),其余为0,要求让每个从坐的椅子都转移到没人坐过的椅子,每个人只能转移一次,且每次操作的代价为abs ( i − j ) ,要求总代价最小。
代码
#include "stdio.h"
#include "algorithm"
#include "math.h"
#include "string.h"
using namespace std;
int a[5009];
int b[5009];
int dp[5000][5000];
//dp[i][j]:第i个人移到第j个椅子和前面i-1个人移到j之前的空椅子的总代价最小
int mmin[5000][5000];
int main()
{
int n,s=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int k;
scanf("%d",&k);
if(k) a[++a[0]]=i;//这儿的a[0]记录着a数组的长度
else b[++b[0]]=i;//这儿的b[0]记录着b数组的长度
//a[1]记录着第一把被人坐的椅子的位子……
//b[1]记录着的一把没人坐的椅子的位子……
s+=k;
}
if(s==0)
{
printf("0\n");
return 0;
}
for(int i=1;i<=a[0];i++)
for(int j=i;j<=b[0];j++)
{
//注意,这里j至少从i开始,因为如果选到更加前面的数,那么就会产生错误。
if(i==j)
dp[i][j]=dp[i-1][j-1]+abs(a[i]-b[j]);
else
dp[i][j]=min(dp[i-1][j-1]+abs(a[i]-b[j]),dp[i][j-1]);
}
printf("%d",dp[a[0]][b[0]]);
}