zoukankan      html  css  js  c++  java
  • ZOJ 1234

    一 题意描述:

    就是在n支筷子里面选取k+8双筷子,每双筷子有三支,其中两支(A,B)比较小,第三支C比较大。下面我们要使k+8双筷子中(A-B)^2之和最小。应当怎样选取?

    二 思路分析:

    我们可以用:dp[i][j]表示从前j个筷子里面选取i双(先只取两只筷子组成一双)筷子时(A-B)^2的最小值。

    那么对于第j支筷子而言:

    我们有dp[i][j]=min{dp[i][j-1],dp[i-1][j-2]+(f[j]-f[j-1])*(f[j]-f[j-1]) | (n-j)>3*(k+8-i) }.其中dp[i][j-1]表示不拿第j支筷子,在第j-1支筷子里面就已经选好了i双筷子。dp[i-1][j-2]表示拿了第j支筷子,那么我们可以想到第j-1只筷子肯定被拿了,而且是和第j支筷子组成一双,那么我们可以推断出在前j-2支筷子里面我们只组成i-1双筷子,即dp[i-1][j-2].

    三 AC代码:

     1 #include<iostream>
     2 # include<cstring>
     3 # include<cstdio>
     4  using namespace std;
     5 long  MAX = 2147483647;
     6 int  dp[1010][5005];
     7  int   f[5005];
     8  int main()
     9  {
    10      int t;
    11      cin>>t;
    12      while(t--)
    13      {
    14          int k,n;
    15          cin>>k>>n;
    16          for(int i=1;i<=n;i++)
    17          cin>>f[i];
    18          memset(dp,0,sizeof(dp));
    19          k+=8;
    20          long temp;
    21          for(int i=1;i<=k;i++)
    22          {
    23              for(int j=2*i;j<=n;j++)
    24              {
    25                  dp[i][j]=MAX;
    26                  if(j>2*i) dp[i][j]=dp[i][j-1];//j>2*i表示第j个没选
    27                  if(n-j>(k-i)*3)
    28                   temp=dp[i-1][j-2]+(f[j]-f[j-1])*(f[j]-f[j-1]);
    29                  if(temp<dp[i][j]) dp[i][j]=temp;
    30              }
    31          }
    32          cout<<dp[k][n]<<endl;
    33      }
    34      return 0;
    35  }
  • 相关阅读:
    1334: 好老师
    poj 2255 Tree Recovery
    2006浙大:简单计算器
    POJ1001(C++处理大数)
    HDU2159(二维完全背包)
    POJ2080:Calendar(计算日期)
    2008上交:Day of Week
    POJ1365:质因数分解
    VIJOS:P1706(舞会)
    POJ2449:K短路
  • 原文地址:https://www.cnblogs.com/khbcsu/p/3867199.html
Copyright © 2011-2022 走看看