【 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 
#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;
}

你可能感兴趣的:(动态规划,算法,shader,java,数据可视化)