VIJOS 1240朴素的网络游戏
朴素的网络游戏
描述
佳佳最近又迷上了某款类似于虚拟人生的网络游戏。在游戏中,佳佳是某旅行团的团长,他需要安排客户住进旅馆。旅馆给了佳佳的旅行团一个房间数的限制。每一个房间有不同的容纳人数和价钱(这个价格是房间的总价格,不是每个人付的)。佳佳决定找到最小的花费,安排参加旅行的人住在这里。但是他遇到了这么一个问题:两个不同性别的人不能住在同一个房间里,除非他们是夫妻;一对夫妻如果在一起住,那么别的人就不能再住进去。你不必让所有的夫妻都单独住在一起。也就是说:
- 1、给你一些房间,告诉你这些房间的容纳人数和价格
- 2.安排一定数量的人住到旅馆里,满足:
- a.不同性别的人如果不是夫妻那么不能住一起。
- b.夫妻如果住在一起,那么房间不能安排其他的人进去。
你来写一个程序帮助佳佳找到安排这些来参加旅行的人住进旅馆所需要的最小花费。
格式
输入格式
第一行有4个用空格隔开的整数m,f,r,c,分别表示参加旅行的男性人数、参加旅行的女性人数、旅馆的房间数、这些男女中有多少对夫妻。注意每一个人不是单身就是和他/她唯一的妻子/丈夫一起参加旅行。
接下来有r行,每行描述了一个房间。每行有两个整数Bi,Pi,它们分别表示每一个房子的容纳人数和价格(无论住多少人,房间的价格不变)。
对于30%的数据,0<=m,f,r<=50;
对于100%的数据,0<=m,f,r<=300,0<=c<=Min(m,f),0<=Bi,Pi<=10。
输出格式
输出为旅行的人订购房间所需要的最小花费。如果没有这样的安排,请输出“Impossible”代替。
样例1
样例输入1
2 1 3 1
3 5
2 10
2 4
样例输出1
9
限制
各测试点5秒
提示
Sample Input #2
1 1 1 0
1 4
Sample Output #2
Impossible
动态规划
dp[i][m][f]:前i个房间住下m个男人和f个女人的最小代价
dp[i][m][f]=min(f[i][m-rs[i]][f]+fy[i],f[i][m][f-rs[i]]+fy[i],(c>0&&rs[i]>1)?f[i][m-1][f-1]:0x3fffffff)
#include<bits/stdc++.h>
using namespace std;
const int maxn=305;
int dp[maxn][maxn][maxn];
int m,f,n,c;
int rs[maxn],hf[maxn];
int minf(int a,int b,int c,int d)
{
return min(min(a,b),min(c,d));
}
int get(int i,int y,int z)
{
if(i==0&&(y>0||z>0))return 0x3f3f3f3f;
if(i>=0&&y<=0&&z<=0)return 0;
if(i>=0&&y>=0&&z>=0)return dp[i][y][z];
if(i>=0&&(y<0||z<0))
{
if(y<0)y=0;if(z<=0)z=0;
return get(i,y,z);
}
}
int main()
{
scanf("%d%d%d%d",&m,&f,&n,&c);
for(int i=1;i<=n;++i)
scanf("%d%d",&rs[i],&hf[i]);
memset(dp,0x3f,sizeof dp);
dp[0][0][0]=0;
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
for(int k=0;k<=f;++k)
dp[i][j][k]=minf(get(i-1,j,k),get(i-1,j-rs[i],k)+hf[i],get(i-1,j,k-rs[i])+hf[i],(rs[i]>=2&&c>=0)?(get(i-1,j-1,k-1)+hf[i]):0x3f3f3f3f);
cout<<dp[n][m][f]<<endl;
return 0;
}