描述

佳佳最近又迷上了某款类似于虚拟人生的网络游戏。在游戏中,佳佳是某旅行团的团长,他需要安排客户住进旅馆。旅馆给了佳佳的旅行团一个房间数的限制。每一个房间有不同的容纳人数和价钱(这个价格是房间的总价格,不是每个人付的)。佳佳决定找到最小的花费,安排参加旅行的人住在这里。但是他遇到了这么一个问题:两个不同性别的人不能住在同一个房间里,除非他们是夫妻;一对夫妻如果在一起住,那么别的人就不能再住进去。你不必让所有的夫妻都单独住在一起。也就是说:
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秒

-----------------------------------------

总存在一个最优解使得只有一对couple在一起或者没有,因为假如有两队,可以男女交换

f[i][j][k]和g[i][j][k]分别表示没有和有一对,转移时除了f向f,g向g外,再考虑g[i][j][k]=min(g[i][j][k],f[i-1][j-1][k-1]+p[i])

【WARN】:1.注意这个转移g[i][j][k]=min(g[i][j][k],f[i-1][j-1][k-1]+p[i]) j和k>=1

2.房间不一定注满人,如果再加一层枚举房间住几个人会很慢,可以把j和k<0的情况从不合法改成从0转移,想当于考虑了房间不满,最多男女各有一个房间不满

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,INF=1e9;
int m,fm,r,c,b[N],p[N];
int f[N][N][N],g[N][N][N]; void dp(){
for(int j=;j<=m;j++) for(int k=;k<=fm;k++) f[][j][k]=g[][j][k]=INF;
f[][][]=;
for(int i=;i<=r;i++)
for(int j=;j<=m;j++)
for(int k=;k<=fm;k++){
f[i][j][k]=f[i-][j][k]; g[i][j][k]=g[i-][j][k];
if(b[i]>=&&j>=&&k>=) g[i][j][k]=min(g[i][j][k],f[i-][j-][k-]+p[i]);
int sj=max(,j-b[i]),sk=max(,k-b[i]);
f[i][j][k]=min(f[i][j][k],f[i-][sj][k]+p[i]),
g[i][j][k]=min(g[i][j][k],g[i-][sj][k]+p[i]);
f[i][j][k]=min(f[i][j][k],f[i-][j][sk]+p[i]),
g[i][j][k]=min(g[i][j][k],g[i-][j][sk]+p[i]);
}
}
int main(){
scanf("%d%d%d%d",&m,&fm,&r,&c);
for(int i=;i<=r;i++) scanf("%d%d",&b[i],&p[i]);
dp(); int ans;
if(c==) ans=f[r][m][fm];
else ans=min(f[r][m][fm],g[r][m][fm]);
if(ans!=INF) cout<<ans;
else cout<<"Impossible";
}
//题解中神犇的滚动数组做法 边读边做
//快了近三倍
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
const int N = + ;
int m,f,r,c;
int dp[N][N][];
int main()
{
scanf("%d%d%d%d",&m,&f,&r,&c); memset(dp,0x3f3f3f3f,sizeof(dp));
dp[m][f][] = dp[m][f][] = ;
for(int i = ; i < r; i++)
{
int a,b;
scanf("%d%d",&a,&b);
for(int i = ; i <= m; i++)
{
for(int j = ; j <= f; j++)
{
int x1 = max(,i-a);
int x2 = max(,j-a);
dp[x1][j][] = min(dp[x1][j][],dp[i][j][] + b);
dp[i][x2][] = min(dp[i][x2][],dp[i][j][] + b);
dp[x1][j][] = min(dp[x1][j][],dp[i][j][] + b);
dp[i][x2][] = min(dp[i][x2][],dp[i][j][] + b);
if(i > && j > && a >= )
dp[i-][j-][] = min(dp[i-][j-][],dp[i][j][] + b);
}
}
}
int d = min(dp[][][],dp[][][]);
if(d == 0x3f3f3f3f)
printf("Impossible");
else
printf("%d",d); }

VIJOS1240 朴素的网络游戏[DP]的更多相关文章

  1. 洛谷 P3343 - [ZJOI2015]地震后的幻想乡(朴素状压 DP/状压 DP+微积分)

    题面传送门 鸽子 tzc 竟然来补题解了,奇迹奇迹( 神仙题 %%%%%%%%%%%% 解法 1: 首先一件很明显的事情是这个最小值可以通过类似 Kruskal 求最小生成树的方法求得.我们将所有边按 ...

  2. 清北学堂2018DP&图论精讲班 DP部分学习笔记

    Day 1 上午 讲的挺基础的--不过还是有些地方不太明白 例1 给定一个数n,求将n划分成若干个正整数的方案数. 例2 数字三角形 例7 最长不下降子序列 以上太过于基础,不做深入讨论 例3 给定一 ...

  3. SGU_390_Tickets(另类数位DP)

    Tickets Time Limit : 1000/500ms (Java/Other)   Memory Limit : 524288/262144K (Java/Other) Total Subm ...

  4. 斜率dp+cdq分治

    写在前面 这个东西应该是一个非常重要的套路......所以我觉得必须写点什么记录一下,免得自己忘掉了 一直以来我的斜率dp都掌握的不算很好......也很少主动地在比赛里想到 写这个的契机是noi.a ...

  5. [51nod 1022] 石子归并v2 [dp+四边形不等式优化]

    题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不 ...

  6. 【BZOJ2286】消耗战(虚树,DFS序,树形DP)

    题意:一棵N个点的树上有若干个关键点,每条边有一个边权,现在要将这些关键点到1的路径全部切断,切断一条边的代价就是边权. 共有M组询问,每组询问有k[i]个关键点,对于每组询问求出完成任务的最小代价. ...

  7. 「USACO16OPEN」「LuoguP3146」248(区间dp

    题目描述 Bessie likes downloading games to play on her cell phone, even though she doesfind the small to ...

  8. Luogu P2858 [USACO06FEB]奶牛零食Treats for the Cows 【区间dp】By cellur925

    题目传送门 做完A Game以后找道区间dp练练手...结果这题没写出来(哭). 和A Game一样的性质,从两边取,但是竟然还有天数,鉴于之前做dp经常在状态中少保存一些东西,所以这次精心设计了状态 ...

  9. 区间DP的瞎扯淡

    写在前面连个引言都不加就直接开1. 区间DP状态常见模板: f[i][j]常常表示第i个到第j个这个区间内达到题目要求,所需要的最小值(最大值) 如: 1. [石子合并](https://www.lu ...

随机推荐

  1. Javascript到PHP加密通讯的简单实现

    其实内容主要来源于上一篇博文,只是重新组织了语言,并做了原理性的阐述,更容易理解:P ----------------------------------------- 华丽的分割线 -------- ...

  2. JavaScript滚动条插件源码

    这是过年的时候自己写的js滚动条插件的源码,做出的效果自己并不满意,正因为做的并不满意所以回头重新巩固和深入学习js,这个插件有如下几个不太满意的地方: 内容的过度效果,可以参阅QQ客户端最近会话列表 ...

  3. vncserver安装

    我的环境是centos6.5,如果没有安装桌面,先执行: # yum groupinstall "X Window System" "Desktop" # yu ...

  4. mysql不同版本和存储引擎选型的验证

    Mysql的版本和存储引擎较多,为了选择最适合业务使用的系统,需要进行一定的验证,本文描述mysql的验证过程和思路. 主要涉及: Mysql的版本 v Mariadb v Tokudb v Orac ...

  5. struts理解

    最近大家都在找工作,我好迷茫,觉得自己会的东西太少了.所以决定开始学习SSH三大框架. 首先是struts. struts是基于mvc模式的框架.(struts其实也是servlet封装,提高开发效率 ...

  6. Android jni简便开发流程

    <Android jni helloworld>中介绍了开发jni helloworld的步骤,本文将介绍jni简便开发流程 ① 写java代码 native 声明本地方法 ② 添加本地支 ...

  7. IOS开发 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

    xcode自7后不再使用http,而是使用https请求,但目前很多网络请求还只是以http请求,我们可以这样解决 info.plist->添加@“App Transport Security ...

  8. Android常用设计模式(二)

    Android常用设计模式之观察者模式 观察者设计模式在Android应用中会经常用到,模式原理类似于这样的场景: 用户订报纸,然后在报社登记,报社来统计用户(添加用户),用户也可以取消订阅,报社删除 ...

  9. TFS中向源代码方案中添加文件

    一些情况下,不能使用VS提供的菜单直接将文件添加到源代码项目,例如该文件是使用TT生成的,或者依赖于其它文件     此时可以在此文件的父级依赖文件上右击,即可添加未受托管的文件     另一种方法, ...

  10. Java Se: Logging 框架说明

    Java Logging 用惯了log4j等日志工具,竟然不知Java还自带了个log工具.今天有空了就来了解一下. 先来看一个简单的例子: public class SystemTest { pri ...