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 }
View Code

 

 

 

 

 

 

 

 

posted @ 2013-08-16 18:44  _雨  阅读(268)  评论(0编辑  收藏  举报