Vijos 1240

题目链接: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大佬帮我改了错。

lz大佬博客:https://www.cnblogs.com/zhuier-xquan/

上一篇:黄金如期回调


下一篇:c语言新手的无奈,几个新手容易犯的错误