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

 

 

 

 

 

 

 

 

你可能感兴趣的:(VJ1061迎春舞会之三人组舞)