1. 程式人生 > 實用技巧 >【 Educational Codeforces Round 93 (Rated for Div. 2) D】Colored Rectangles

【 Educational Codeforces Round 93 (Rated for Div. 2) D】Colored Rectangles

題目連結

連結

翻譯

題目描述挺繞的。

\(3\) 種顏色的棍子吧。

每種顏色棍子提供的時候都是一對一對給的(也即兩根兩根地給,然後顏色相同,長度也相同)。

每種顏色有 \(limited\) 對不同長度棍子。

然後題目的意思是說選兩種不同顏色,然後分別選一對棍子。(這樣就有 \(4\) 根棍子了)

組成矩形,相同顏色的在對邊(長度相同所以都在對邊)。

問你這些棍子組成的矩形和的最大值是多少。

題解

肯定貪心地選擇長的棍子(這樣有剩下的話,剩下的也是短棍子),長棍子更容易組成面積更大的矩形嘛。

然後 \(N\) 這麼小,就很明顯是一個 \(DP\) 了。

\(f[i][j][k]\) 表示紅色剩 \(i\)

對, 綠色剩 \(j\) 對, 黑色剩 \(k\) 對能組成的最大面積值。

初始值的話就全 \(0\) 就好。但實際上是 \(f[i][0][0],f[0][j][0],f[0][0][k]\) 這些為 \(0\),這些狀態沒辦法組成兩堆了。

狀態轉移方程就類似 \(f[i][j][k] = max(f[i][j][k],f[i-1][j-1][k]+r[i]*g[j])\) 這樣。

程式碼

#include <bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 200;

int R,G,B;
int r[N + 10],g[N + 10],b[N + 10];
LL f[N + 10][N + 10][N + 10];

bool cmp(int a,int b){
    return a < b;
}

int main(){
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> R >> G >> B;
    for (int i = 1;i <= R; i++){
        cin >> r[i];
    }
    sort(r+1,r+1+R,cmp);
    for (int i = 1;i <= G; i++){
        cin >> g[i];
    }
    sort(g+1,g+1+G,cmp);
    for (int i = 1;i <= B; i++){
        cin >> b[i];
    }
    sort(b+1,b+1+B,cmp);
    LL ans = 0;
    for (int i = 0;i <= R; i++){
        for (int j = 0;j <= G; j++){
            for (int k = 0; k <= B; k++){
                if (i > 0 && j > 0){
                    f[i][j][k] = max(f[i][j][k],f[i-1][j-1][k] + r[i]*g[j]);
                }
                if (i > 0 && k > 0){
                    f[i][j][k] = max(f[i][j][k],f[i-1][j][k-1] + r[i]*b[k]);
                }
                if (j > 0 && k > 0){
                    f[i][j][k] = max(f[i][j][k],f[i][j-1][k-1] + g[j]*b[k]);
                }
                ans = max(ans,f[i][j][k]);
            }
        }
    }
    cout << ans << endl;
    return 0;
}