1. 程式人生 > 實用技巧 >Educational Codeforces Round 97 (Rated for Div. 2)部分題解

Educational Codeforces Round 97 (Rated for Div. 2)部分題解

Problem A

我們構造以l為a,那麼轉換一下題目的方程,就可以發現,\(2*l>r\)的時候條件一定成立。

Problem B

不知道什麼鬼,猜一發就能過了。大概就是連續的0和1的數量取一個max。

Problem C

本來是想貪心的,但是這個題目太難搞了。最後思路還是走向dp,首先我們分析最後的狀態一定是所有的菜都被在某一個時間拿走。那麼在某時刻拿走當前菜的狀態取決於前一盤菜被拿走的時候的狀態,於是我們需要列舉前一個菜被拿走的時間,狀態轉移方程為:\(dp[i][j]=max (dp[i][j],dp[i-1][k]+w)\).
程式碼實現

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10;
int dp[maxn][maxn];
int n;
void check_min (int &a,int b) {a=min (a,b);}

int main () {
  int t;
  scanf ("%d",&t);
  while (t--) {
    scanf ("%d",&n);
    vector <int> v(n+1);
    for (int i=1;i<=n;i++) scanf ("%d",&v[i]);
    memset (dp,0x7f,sizeof (dp));
    for (int i=0;i<=2*n;i++) dp[i][0]=0;
    sort (v.begin ()+1,v.end ());
    for (int i=1;i<=n;i++) 
      for (int j=i-1;j<=2*n;j++) 
        for (int k=j+1;k<=2*n;k++) {
          check_min (dp[i][k],dp[i-1][j]+abs (v[i]-k));
        }
    int ans=0x3f3f3f3f;
    for (int i=1;i<=2*n;i++) check_min (ans,dp[n][i]);
    printf ("%d\n",ans);
  }
  return 0;
}