D. Colored Rectangles
原题链接:
https://codeforces.ml/contest/1398/submission/89947207
题目大意:
有三种颜色的线条,红色有R对,绿色有G对,黑色有B对,每次需要选择两种不同颜色的线条组成一个长方形,求组成的长方形最大面积和是多少。
解题思路:
选一种线条的时候,一定是从最长的开始,所以需要先排个序,然后开一个三维数组,$dp_{i,j,k}$记录选的三种颜色的情况,$i,j,k$都从小到大遍历,然后求出$dp_{i,j,k}$有三种状态推出的最大值(最多三种状态)。
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 typedef pair<int,int> pi;
5 typedef complex <double> cp;
6 #define debug(a) cout<<#a<<":"<<a<<endl;
7 #define fr freopen("in.txt","r",stdin);
8 #define Fill(x,a) memset(x,a,sizeof(x))
9 #define cpy(a,b) memcpy(a,b,sizeof(a))
10 const double PI = acos(-1);
11 const int INF=0x3f3f3f3f;
12 const int N=1e6+7;
13 const int mod=1e9+7;
14 int maxn,minn;
15 int T,n,m,q;
16 int r[N],b[N],g[N];
17 int nr,ng,nb;
18 int dp[205][205][205];
19 int ans;
20
21 int main(){
22 cin>>nr>>ng>>nb;
23 for(int i=1;i<=nr;i++){
24 scanf("%d",r+i);
25 }
26 for(int i=1;i<=ng;i++){
27 scanf("%d",g+i);
28 }
29 for(int i=1;i<=nb;i++){
30 scanf("%d",b+i);
31 }
32 sort(r+1,r+nr+1);
33 sort(g+1,g+ng+1);
34 sort(b+1,b+nb+1);
35 reverse(r+1,r+nr+1);
36 reverse(g+1,g+ng+1);
37 reverse(b+1,b+nb+1);
38 dp[0][0][0]=0;
39 for(int i=0;i<=nr;i++){
40 for(int j=0;j<=ng;j++){
41 for(int k=0;k<=nb;k++){
42 if(i&&j){
43 dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]+r[i]*g[j]);
44 }
45 if(i&&k){
46 dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-1]+r[i]*b[k]);
47 }
48 if(k&&j){
49 dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-1]+g[j]*b[k]);
50 }
51 ans=max(ans,dp[i][j][k]);
52 }
53 }
54 }
55 cout<<ans<<endl;
56
57
58
59 return 0;
60 }
61