题意:给出红绿蓝三种颜色的木棍,每种长度的木棍每一次给一对,现在每次取两对木棍,组成由两种颜色组成的长方形,求最后长方形的面积之和最大是多少 。
一开始以为是贪心,后来贪心代码写完才发现情况比较复杂,就立马想到是dp了。
dp[i][j][k]代表R取了前i个,G取了前j个,B取了前k个的答案。
如果当前状态是由取出R,G两个集合的元素得到的,那么(dp[i][j][k]=dp[i-1][j-1][k]+a[i]*b[j])
如果当前状态是由取出R,B两个集合的元素得到的,那么(dp[i][j][k]=dp[i-1][j][k-1]+a[i]*c[k])
如果当前状态是由取出G,B两个集合的元素得到的,那么(dp[i][j][k]=dp[i][j-1][k-1]+b[j]*c[k])
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<vector> #include<map> #include<set> #include<queue> //#define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; double eps=1e-10; ll mod=1e15+7; const int INF =0x3f3f3f; const int MAXN=2e3+10; const int maxn = 1e5+10; //ll inf=100000000000000; //template<typename T>inline void read(T &x) //{ // x=0; // static int p;p=1; // static char c;c=getchar(); // while(!isdigit(c)){if(c=='-')p=-1;c=getchar();} // while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();} // x*=p; //} typedef unsigned long long ull; int a[210],b[210],c[210]; ll dp[210][210][210]; int main() { int R,G,B; cin>>R>>G>>B; for(int i=1;i<=R;i++) cin>>a[i]; for(int i=1;i<=G;i++) cin>>b[i]; for(int i=1;i<=B;i++) cin>>c[i]; sort(a+1,a+1+R,greater<int>()); sort(b+1,b+1+G,greater<int>()); sort(c+1,c+1+B,greater<int>()); memset(dp,-0x3f,sizeof dp); dp[0][0][0]=0; 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&&j&&k) dp[i][j][k]=max(dp[i-1][j-1][k]+a[i]*b[j],max(dp[i-1][j][k-1]+a[i]*c[k],dp[i][j-1][k-1]+b[j]*c[k])); else if(i&&j) dp[i][j][k]=dp[i-1][j-1][k]+a[i]*b[j]; else if(i&&k) dp[i][j][k]=dp[i-1][j][k-1]+a[i]*c[k]; else if(j&&k) dp[i][j][k]=dp[i][j-1][k-1]+b[j]*c[k]; ans=max(ans,dp[i][j][k]); } cout<<ans<<endl; return 0; }