回档|朴素的网络游戏

描述
佳佳最近又迷上了某款类似于虚拟人生的网络游戏。在游戏中,佳佳是某旅行团的团长,他需要安排客户住进旅馆。旅馆给了佳佳的旅行团一个房间数的限制。每一 个房间有不同的容纳人数和价钱(这个价格是房间的总价格,不是每个人付的)。佳佳决定找到最小的花费,安排参加旅行的人住在这里。但是他遇到了这么一个问 题:两个不同性别的人不能住在同一个房间里,除非他们是夫妻;一对夫妻如果在一起住,那么别的人就不能再住进去。你不必让所有的夫妻都单独住在一起。也就 是说:
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”代替。
样例输入
2 1 3 1
3 5
2 10
2 4
样例输出
9
限制
各测试点5秒
OIBH命题组提供 By 月影

解析:dp[l][i][j][k]:l:前l个房间。i:i个男人。j:j个女人。k=0 or 1,表示是否有夫妻。显然夫妻顶多有一对在一间房子里(我觉得不考虑应该也没啥问题),否则不是最优。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;

int m,f,r,c;
int b[500],p[500];
int dp[301][301][301][2];

int main()
{
    cin >> m >> f >> r >> c;
    for (int i=1; i<=r; i++) cin >> b[i] >> p[i];
    memset(dp,127,sizeof(dp));
    int tot=dp[0][0][0][0];
    dp[0][0][0][0]=0;
    for (int l=1; l<=r; l++)
        for (int i=0; i<=m; i++)
            for (int j=0; j<=f; j++)
            {
                if (b[l]>=2 && j>=1 && i>=1) dp[l][i][j][1]=min(dp[l-1][i-1][j-1][0]+p[l],dp[l-1][i][j][1]);
                dp[l][i][j][0]=min(dp[l-1][i][j][0],dp[l][i][j][0]);
                for (int o=1; o<=b[l]; o++)
                {
                    if (i-o>=0)
                    {
                        dp[l][i][j][0]=min(dp[l-1][i-o][j][0]+p[l],dp[l][i][j][0]);  
                        dp[l][i][j][1]=min(dp[l-1][i][j][1],dp[l-1][i-o][j][1]+p[l]);       
                    }
                    if (j-o>=0)
                    {
                        dp[l][i][j][0]=min(dp[l-1][i][j-o][0]+p[l],dp[l][i][j][0]);
                        dp[l][i][j][1]=min(dp[l-1][i][j-o][1]+p[l],dp[l][i][j][1]);
                    }
                }
            }
    int ans=min(dp[r][m][f][0],dp[r][m][f][1]);
    if (ans==tot) cout << "Impossible" << endl;
      else cout << ans;
    return 0;
}

 

posted @ 2015-04-05 08:29  竹夭公子  阅读(211)  评论(0编辑  收藏  举报