题目链接:https://vijos.org/p/1240、
稍微经过思考可发现如果有两对夫妻,假如把他们拆散,男男一起,女女一起,不会更劣,反而可能更优,因为房间里可能还可以放下更多的人。
所以,最优情况可能没有夫妻住在一起或者只有一对夫妻住在一起。
用dp[j][k][0]表示安排j个男的,k个女的,没有夫妻所用的最小花费,dp[j][k][1]表示安排j个男的,k个女的,有一对夫妻所用的最小花费。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int m,f,r,c; int dp[310][310][2]; int b[310],p[310]; int main() { scanf("%d%d%d%d",&m,&f,&r,&c); for(int i=1;i<=r;i++) { scanf("%d%d",&b[i],&p[i]); } memset(dp,0x3f,sizeof(dp)); dp[0][0][0] = 0; dp[0][0][1] = 0; for(int i=1;i<=r;i++) { for(int j=m;j>=0;j--) { for(int k=f;k>=0;k--) { if(j>=b[i]) { dp[j][k][0]=min(dp[j][k][0],dp[j-b[i]][k][0]+p[i]); dp[j][k][1]=min(dp[j][k][1],dp[j-b[i]][k][1]+p[i]); } else { dp[j][k][0]=min(dp[j][k][0],dp[0][k][0]+p[i]); dp[j][k][1]=min(dp[j][k][1],dp[0][k][1]+p[i]); } if(k>=b[i]) { dp[j][k][0]=min(dp[j][k][0],dp[j][k-b[i]][0]+p[i]); dp[j][k][1]=min(dp[j][k][1],dp[j][k-b[i]][1]+p[i]); } else{ dp[j][k][0]=min(dp[j][k][0],dp[j][0][0]+p[i]); dp[j][k][1]=min(dp[j][k][1],dp[j][0][1]+p[i]); } if(j>=1&&k>=1&&c>=1&&b[i]>=2) { dp[j][k][1]=min(dp[j][k][1],dp[j-1][k-1][0]+p[i]); } } } } int ans=min(dp[m][f][0],dp[m][f][1]); if(ans==0x3f3f3f3f) ans=-1; printf("%d",ans); return 0; }
感谢lz大佬帮我改了错。