VJ1061迎春舞会之三人组舞
推了半个下午。。写的三重超时了 加了点单调队列的思想 优化了下过了
dp[i][j] 第二组的最右边的人选第J个人 那最左边肯定选第j-1个人 肯定是选相邻的
dp[i][j] = min(o,dp[i-1][j-2]+(h[j]-h[j-1])*(h[j]-h[j-1])) 加个变量o保存 到j为止 最优的一个位置 j-2得满足条件
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #define N 5010 6 #define M 3010 7 #define INF 0xfffffff 8 using namespace std; 9 int dp[M][N],h[N]; 10 int main() 11 { 12 int i,j,n,m,g; 13 scanf("%d%d",&m,&n); 14 for(i = 1; i <= n ;i++) 15 scanf("%d",&h[i]); 16 for(i = 1; i <= m ;i++) 17 for(j = 1; j <= n ;j++) 18 dp[i][j] = INF; 19 int o = INF; 20 for(i = 2 ; i < n ;i++) 21 { 22 dp[1][i] = min(o,(h[i]-h[i-1])*(h[i]-h[i-1])); 23 o = min(dp[1][i],o); 24 } 25 for(i = 2 ; i <= m ; i++) 26 { 27 int o = INF; 28 for(j = 2*i ; j < n-(m-i)*3 ;j++) 29 { 30 if(j-2<(n-(m-i+1)*3)) 31 dp[i][j] = min(o,dp[i-1][j-2]+(h[j]-h[j-1])*(h[j]-h[j-1])); 32 else 33 dp[i][j] = min(o,dp[i-1][j-3]+(h[j]-h[j-1])*(h[j]-h[j-1])); 34 o = min(o,dp[i][j]); 35 } 36 } 37 printf("%d\n",dp[m][n-1]); 38 return 0; 39 }