题目描述
在猴村有一条笔直的山路,这条山路很窄,宽度忽略不计。有 n 只猴子正站在山路上静静地观望今天来参加比赛的各位同学。用一个正整数 Xi 表示第 i 只猴子所站位置,任意两只猴子的所站位置互不相同。在这条山路的 m 个位置上种着一些高大的树木,正整数 Yj 表示第 j 棵树木所在的位置,任意两棵树的位置互不相同。
正当猴子们聚精会神的欣赏各位高超编程技能 聚精会神的欣赏各位高超编程技能时,一只老虎大摇摆的走了过来。猴子们吓得直冒冷汗,第一反应就是找棵大树爬上去这样能避免被老虎咬死或者吃掉(不考虑老虎上树问题)。
在位置 a 的猴子跑到在位置 b 的大树上,需要消耗能量为 ∣a−b∣(即 a−b 的绝对值)。为了尽可能有效利用这些大树避难,每棵上至少要一只猴子。 请编程计算 n 只猴子全部上树最少需要消耗多少能量?
输入格式
输入共 4 行。
第 1 行一个整数 n,表示猴子的数量。
第 2 行 n 个整数,第 i 个整数 Xi 表示第 i 只猴子所在的位置。
第 3 行一个整数 m,表示大树的数量。
第 4 行 m 个整数,第 j 个整数表示第 j 棵大树所在的位置。
输出格式
输出一行,一个整数表示 n 只猴子全部上树最少需要消耗的能量。
输入输出样例
输入 #1复制
3 1 4 5 2 3 8
输出 #1复制
6
输入 #2复制
3 3 1 10 2 8 3
输出 #2复制
4
说明/提示
30% 的数据,1≤n≤500,1≤Xi,Yi≤10^5。
100% 的数据,1≤n≤5000,1≤m≤n,1≤Xi,Yi≤10^9。
思路:
考虑动态规划。
设 f [ i ][ j ] 为前 i 只猴子上前 j 棵树花费的最小能量。
第 i 只猴子要么共享第 j 棵树,要么独占第 j 棵树。
所以有 f [ i ][ j ] = min ( f [ i - 1][ j ],f [ i - 1][ j - 1] ) + 距离之差 。
提交代码。
咦?MLE了?
改成滚动数组
咦?WA了?
改long long
十年oi一场空
不开long long见祖宗
AC了
Code:
#include<bits/stdc++.h>
using namespace std;
long long n,mo[5005],tree[5005],m,f[2][5005],i=1,j=1;
int main(){
cin>>n;
for(i=1;i<=n;i++)cin>>mo[i];
cin>>m;
for(i=1;i<=m;i++)cin>>tree[i];
sort(mo+1,mo+n+1);
sort(tree+1,tree+m+1);
memset(f,0x7f,sizeof(f));
f[1][1]=abs(mo[1]-tree[1]);
for(i=2;i<=n;i++)
for(j=1;j<=m;j++)
f[i%2][j]=min(f[(i-1)%2][j],f[(i-1)%2][j-1])+abs(mo[i]-tree[j]);
cout<<f[n%2][m];
}