1398D 1800的题,简单dp,但架不住我dp菜啊
题意:现在给你R对红色小棒,对应的长度为ri, G对绿色小棒,对应长度为gi, B对蓝色小棒,对应长度为bi,现在让你把这些小棒组合成矩形(四根小棒),要求为对应的边颜色要一致,相邻的边颜色不一致,问你能得到的最大的矩形面积。
思路:一开始想的是贪心,但后来想到了一个反例如下:
6 6
6 6
5 5 5 5,
如果按照贪心的话就是6X6X2,但是实际上他最大的面积是5X6X4,所以要用dp进行暴搜,然后取最优
开个三维数组dp[i][j][k],表示R只考虑前i个,G只考虑前j个,B只考虑前k个,状态转移为:
可以是从dp[i-1][j-1][k]增加一对R和G,也就是i和j各自+1的情况转化而来,
也可以是从dp[i-1][j][k-1]增加一对R和B,也就是i和k各自+1的情况转化而来,
也可以是从dp[i][j-1][k-1]增加一对G和B,也就是j和k各自+1的情况转化而来。
代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define rep(i, a, n) for(int i = a; i <= n; i++)
#define per(i, a, n) for(int i = n; i >= a; i--)
#define IOS std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define fopen freopen("file.in","r",stdin);freopen("file.out","w",stdout);
#define fclose fclose(stdin);fclose(stdout);
const int inf = 1e9;
const ll onf = 1e18;
const int maxn = 200+10;
inline int read(){
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int a[maxn], b[maxn], c[maxn], dp[maxn][maxn][maxn];
bool cmp(int x, int y){
return x>y;
}
signed main(){
int R=read(), G=read(), B=read();
rep(i,1,R) a[i]=read();
rep(i,1,G) b[i]=read();
rep(i,1,B) c[i]=read();
sort(a+1, a+1+R, cmp), sort(b+1, b+1+G, cmp), sort(c+1, c+1+B, cmp);
int ans = 0;
rep(i,0,R){
rep(j,0,G){
rep(k,0,B){
if(i&&j) dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k]+a[i]*b[j]);
if(i&&k) dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k-1]+a[i]*c[k]);
if(k&&j) dp[i][j][k] = max(dp[i][j][k], dp[i][j-1][k-1]+b[j]*c[k]);
ans = max(ans, dp[i][j][k]);
}
}
}
printf("%d\n", ans);
return 0;
}