思考:
想了很久,感觉这个dp方程没法推导啊。
之后看了看题解才发现原来是自己把自己框在原地了。
首先题目中给了 男生 女生 情侣 房间 花费这几个信息。
看到 房间以及最小花费很容易想到背包 dp[x]...[x]+cost[i]这种的。
男生和女生我们可以看做二维费用背包,但是夫妻这个怎么处理呢。
仔细想想如果有2对夫妻 3对夫妻的情况 我们可不可以看做 2个男一个房 2个女一个房 3个男一个房3个女一个房(这种情况比夫妻住还优)的情况。
也就是可以忽略夫妻这个条件,不过要特判一下夫妻只有一个男的一个女的且为情况的情况就好了。
#include <cstdio> #include <algorithm> #include <cstring> using std::min; const int INF = 0x3f3f3f3f; int m,f,r,c; int cost[305],Size[305]; int dp[305][305],Min=INF; int main(){ memset(dp,INF,sizeof(dp)); scanf("%d%d%d%d",&m,&f,&r,&c); for(int i=1;i<=r;i++){ scanf("%d%d",&Size[i],&cost[i]); } if(m==1 && f==1 && c==1){ int fuck = 2333333; for(int i=1;i<=r;i++){ if(Size[i]>=2 && cost[i]<fuck) fuck = cost[i]; } printf("%d\n",fuck); return 0; } dp[0][0]=0; c=0; for(int i=1;i<=r;i++){ for(int k=m;k>=0;k--){ for(int l=f;l>=0;l--){ if(k>Size[i])dp[k][l] = min(dp[k][l],dp[k-Size[i]][l]+cost[i]); else dp[k][l] = min(dp[k][l],dp[0][l]+cost[i]); if(l>Size[i])dp[k][l] = min(dp[k][l],dp[k][l-Size[i]]+cost[i]); else dp[k][l] = min(dp[k][l],dp[k][0]+cost[i]); } } } Min = min(Min,dp[m][f]); if(Min==INF) printf("-1"); else printf("%d\n",Min); return 0; }
时间: 2024-10-12 19:31:52