D. Colored Rectangles(动态规划问题) Educational Codeforces Round 93 (Rated for Div. 2)

原题链接: http://codeforces.com/contest/1398/problem/D

D. Colored Rectangles(动态规划问题) Educational Codeforces Round 93 (Rated for Div. 2)_第1张图片
样例:

input
1 1 1
3
5
4
output
20
input
2 1 3
9 5
1
2 8 5
output
99
input
10 1 1
11 7 20 15 19 14 2 4 13 14
8
11
output
372

题意: 你有三对彩棒的多重集合,即G,B,C三个数组,每个数组中元素代表的是对应彩棒的长度。你可以选择颜色不同的两对彩棒形成一个矩形。即形成的矩形它们的相对侧是相同的颜色,而相邻的侧是不同的颜色。问你能形成的总矩形面积之和最大值为多少?

解题思路: 由于很多信息我们都不明了,我们对于这个问题会比较模糊。但我们仔细想想我们求总矩形面积之和的最大值问题(即最优解)是不是可以转换为更小的子问题?设我们可以构造的最大矩形数为 n n n,(注意:最大矩形数是一定固定的)那么该状态的最优解是不是可以转换为矩形数为 n − 1 n-1 n1的最优解+当前可构建矩形面积的最大值。我们用 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示用去了 i i i个R颜色彩棒, j j j个G个颜色彩棒, k k k个C颜色彩棒,那么我们表示矩形数为 n − 1 n-1 n1自然对应的彩棒数要减2了,这里注意有三种情况都要判断。有了这个思路,我们是不是可以利用动态规划的思想自底向上(当然也可以自顶向下,利用递归,但占空间量肯定很大。),OK,我们的状态转移方程,具体看代码即可。

AC代码:

/*
*邮箱:[email protected]
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 200+2;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int r,g,c;
int R[maxn],G[maxn],C[maxn];
int dp[maxn][maxn][maxn];
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>r>>g>>c){
		memset(dp,0,sizeof(dp));
		rep(i,0,r-1)cin>>R[i];
		rep(i,0,g-1)cin>>G[i];
		rep(i,0,c-1)cin>>C[i];
		sort(R,R+r);sort(G,G+g);sort(C,C+c);
		//排序。
		rep(i,0,r){
			rep(j,0,g){
				rep(k,0,c){
					if(i>0&&j>0){
						dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]+R[i-1]*G[j-1]); //状态转移
					}
					if(i>0&&k>0){
						dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-1]+R[i-1]*C[k-1]); //状态转移
					}
					if(j>0&&k>0){
						dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-1]+G[j-1]*C[k-1]); //状态转移
					}
				}
			}
		}
		cout<<dp[r][g][c]<<endl;
	}
	return 0;
}

你可能感兴趣的:(动态规划,#,CF,DP,CF)