题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1500
题目和前面的搬寝室很像,不过要多留一只筷子,且这只筷子的长度要大于前面俩只得长度。采用滚动数组来作吧!!主要是为了习惯滚动数组,这样空间上会由一定的节省。
题目已经给定的事非降序排序,所以排序就可以省去了,在处理时,采用预留的方法来解决第三只筷子的问题。
代码:dp[i%2][3*i]=dp[(i-1)%2][3*i-2]+(q[3*i]-q[3*i-1])*(q[3*i]-q[3*i-1]); 在求第i组筷子的时候,前面的有3*i-2只筷子,但是组成的i-1组筷子时,至多用3*i-3只筷子,所以就预留了一只较长的筷子。(可以是前面3*i-2里面的任意一只)。
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int q[5008],dp[2][5008];
int main(){
int n,t,k,i,j;
scanf("%d",&t);
while(t--){
scanf("%d%d",&k,&n);
for(i=n;i>=1;i--){
scanf("%d",&q[i]);
}
k+=8;
memset(dp,0,sizeof(dp));
for(i=1;i<=k;i++){
dp[i%2][3*i]=dp[(i-1)%2][3*i-2]+(q[3*i]-q[3*i-1])*(q[3*i]-q[3*i-1]);
for(j=3*i+1;j<=n;j++){
dp[i%2][j]=min(dp[i%2][j-1],dp[(i-1)%2][j-2]+(q[j]-q[j-1])*(q[j]-q[j-1])); //取最小的组合
}
}
printf("%d\n",dp[k%2][n]);
}
return 0;
}