codeforces D. Colored Rectangles

codeforces D. Colored Rectangles_第1张图片

题目

题意:

给你三个序列,你每次可以选择三个序列中的两个元素,但不能是相同序列的,然后进行相乘,问最后的相乘的和最大是多少。

思路:

我 们 假 设 此 时 三 个 序 列 各 选 了 i , j , k 个 数 字 a n s = d p [ i ] [ j ] [ k ] , 那 么 当 我 们 此 时 选 择 第 i + 1 和 j + 1 个 数 字 的 时 候 , 那 么 此 时 a n s = d p [ i ] [ j ] [ k ] + r [ i + 1 ] ∗ g [ i + 1 ] , 同 理 我 们 就 可 以 得 出 状 态 方 程 : 我们假设此时三个序列各选了i,j,k个数字ans=dp[i][j][k],那么当我们此时选择第i+1和j+1个数字的时候,那么此时ans=dp[i][j][k]+r[i+1]*g[i+1],同理我们就可以得出状态方程: i,j,kans=dp[i][j][k],i+1j+1,ans=dp[i][j][k]+r[i+1]g[i+1],: d p [ i ] [ j ] [ k ] = { m a x ( d p [ i ] [ j ] [ k ] , d p [ i − 1 ] [ j − 1 ] [ k ] + r [ i ] ∗ g [ j ] ) i>0&&j>0 m a x ( d p [ i ] [ j ] [ k ] , d p [ i − 1 ] [ j ] [ k − 1 ] + r [ i ] ∗ b [ k ] ) i>0&&k>0 m a x ( d p [ i ] [ j ] [ k ] , d p [ i ] [ j − 1 ] [ k − 1 ] + g [ j ] ∗ b [ k ] ) j>0&&k>0 dp[i][j][k]=\begin{cases}max(dp[i][j][k], dp[i-1][j-1][k]+r[i]*g[j])& \text{i>0\&\&j>0}\\max(dp[i][j][k],dp[i-1][j][k-1]+r[i]*b[k])& \text{i>0\&\&k>0}\\max(dp[i][j][k],dp[i][j-1][k-1]+g[j]*b[k]) &\text{j>0\&\&k>0}\end{cases} dp[i][j][k]=max(dp[i][j][k],dp[i1][j1][k]+r[i]g[j])max(dp[i][j][k],dp[i1][j][k1]+r[i]b[k])max(dp[i][j][k],dp[i][j1][k1]+g[j]b[k])i>0&&j>0i>0&&k>0j>0&&k>0

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <class T>
inline void read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return ;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1:1;
    ret = (c == '-') ? 0:(c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return ;
}
inline void outi(int x) {if (x > 9) outi(x / 10);putchar(x % 10 + '0');}
inline void outl(ll x) {if (x > 9) outl(x / 10);putchar(x % 10 + '0');}
const int maxn = 210;
int rr[maxn], gg[maxn], bb[maxn], dp[maxn][maxn][maxn];
int main() {
    int r, g, b; read(r), read(g), read(b);
    for (int i = 1; i <= r; i++) read(rr[i]);
    for (int i = 1; i <= g; i++) read(gg[i]);
    for (int i = 1; i <= b; i++) read(bb[i]);
    sort(rr + 1, rr + r + 1, less<int>());
    sort(gg + 1, gg + g + 1, less<int>());
    sort(bb + 1, bb + b + 1, less<int>());
    for (int i = 0; i <= r; i++) {
        for (int j = 0; j <= g; j++) {
            for (int k = 0; k <= b; k++) {
                if (i && j) dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - 1][k] + rr[i] * gg[j]);
                if (i && k) dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k - 1] + rr[i] * bb[k]);
                if (j && k) dp[i][j][k] = max(dp[i][j][k], dp[i][j - 1][k - 1] + gg[j] * bb[k]);
            }
        }
    }
    printf("%d", dp[r][g][b]);
    return 0;
}

你可能感兴趣的:(codeforces)