链接:http://acdream.info/problem?

pid=1409

题意:整个国家有n座城市,每座城市有三种粉丝。

第一种一周看一场音乐剧,挑选的音乐剧是已经在周围城市播放上演过的次数最多的音乐剧中的随机一个。

另外一种每天看一场音乐剧,挑选的是在本城市上映的音乐剧中的随机一个。

第三种每天看一场音乐剧,挑选的是在本城市以及周围城市中上映的音乐剧中的随机一个。

周围的城市是指这座城市与当前城市之间存在路径。

我如今要带着一部音乐剧环游全国(能够坐飞机,不用走路径),每座城市呆一周,而且还存在其它m座城市在这n周内绕国上映(也可能放假),问我这个音乐剧所能吸引到的粉丝的总数的期望是多少。

思路:首先要模拟找出每座城市每周的上映音乐剧数量。每座城市每周周围的上映的音乐剧数,每一个音乐剧在每周每座城市内存在的信息数。

然后用状态压缩,dp[i][j]表示第i周状态为j的条件下能吸引到的粉丝总数。

这题比較繁琐。模拟过程比較蛋疼。

代码:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define eps 1e-8
#define INF 0x7fffffff
#define PI acos(-1.0)
#define seed 31//131,1313
//#define LOCAL
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
double city[15][5];
bool vis[15][15][15];//音乐剧,周,城市
bool now[15][15][15];
int V[15][15];
int top[15];
int aa[15][15][15];//音乐剧,周。城市的信息数
int ans[15];
int road[15];
int Pow[15];
int cc[15][15];//周,城市的上映音乐剧数
int dd[15][15];//周,相邻以及本身上映的音乐剧数
double dp[15][1500];
int p[15][1500];
void init()
{
Pow[0]=1;
for(int i=1; i<=10; i++)
Pow[i]=Pow[i-1]*2;
return ;
}
int main()
{
init();
int n,m,kk,c;
scanf("%d%d%d",&n,&m,&kk);
for(int i=0; i<n; i++)
scanf("%lf%lf%lf",&city[i][0],&city[i][1],&city[i][2]);
for(int i=1; i<=m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
V[u-1][top[u-1]++]=v-1;
V[v-1][top[v-1]++]=u-1;
}
for(int i=1; i<=kk; i++)//剧
{
for(int j=1; j<=n; j++)//周
{
scanf("%d",&c);
c--;
if(j!=1)
for(int k=0; k<n; k++)
vis[i][j][k]=vis[i][j-1][k];
vis[i][j][c]=1;
now[i][j][c]=1;
cc[j][c]++;
dd[j][c]++;
for(int k=0; k<top[c]; k++)
dd[j][V[c][k]]++;
}
}
for(int i=1; i<=kk; i++) //音乐剧
for(int j=1; j<=n; j++) //周
for(int k=0; k<n; k++) //城市
for(int l=0; l<top[k]; l++)
{
if(vis[i][j][V[k][l]])
aa[i][j][k]++;
}
int mos=(1<<n);
for(int i=0; i<=n; i++)
for(int j=0; j<mos; j++)
dp[i][j]=-1;
dp[0][0]=0;
for(int i=1; i<=n; i++)//周
{
for(int j=1; j<mos; j++)//状态
{
for(int k=0; k<n; k++)//到的城市
{
//cout<<k<<endl;
int res=0;
if(j-Pow[k]<0)
break;
if(dp[i-1][j-Pow[k]]!=-1)
{
for(int l=0; l<top[k]; l++)
if(Pow[V[k][l]]&j)
res++;
int flag = 0;
double tot = 0;
for(int l=1; l<=kk; l++)
{
if(aa[l][i][k]>res&&now[l][i][k])
{
flag = 1;
break;
}
else if(aa[l][i][k]==res&&now[l][i][k])
tot++;
}
double all = 0;
if(flag == 0)
all+=city[k][0]/(tot+1);
all+=city[k][1]*7/(cc[i][k]+1);
all+=city[k][2]*7/(dd[i][k]+1);
for(int ii=0; ii<top[k]; ii++)
{
int pos=V[k][ii];
all+=city[pos][2]*7/(dd[i][pos]+1);
}
if(all+dp[i-1][j-Pow[k]]>dp[i][j])
{
dp[i][j]=all+dp[i-1][j-Pow[k]];
p[i][j]=k;
}
}
}
}
}
int nn=mos-1;
int way[15],ttt=0;
for(int i=n; i>=1; i--)
{
//cout<<p[i][nn]<<endl;
way[ttt++]=p[i][nn];
nn-=Pow[p[i][nn]];
}
printf("%.8lf\n",dp[n][mos-1]);
for(int i=ttt-1;i>=0;i--)
{
if(i==ttt-1)
printf("%d",way[i]+1);
else printf(" %d",way[i]+1);
}
printf("\n");
return 0;
}

acdream 1409 Musical 状压DP的更多相关文章

  1. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  2. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  3. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  4. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  5. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  6. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  7. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

  8. 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP

    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...

  9. 【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP

    [BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M< ...

随机推荐

  1. socket 基础知识

    PHP使用Berkley的socket库来创建它的连接.socket只不过是一个数据结构.你使用这个socket数据结构去开始一个客户端和服务器之间的会话.这个服务器是一直在监听准备产生一个新的会话. ...

  2. Linux makefile教程之make运行八[转]

    make 的运行 —————— 一 般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让 make重编译某些文件, ...

  3. GitHub的代码托管和使用方法

    原文  GitHub托管 借助GitHub托管你的项目代码 PS:话说自己注册了GitHub都很久了,却没有怎么去弄,现在系统学习一下,也把自己的学习经历总结下来share给大家,希望大家都能把Git ...

  4. 简单地Android中图片的三级缓存机制

    我们不能每次加载图片的时候都让用户从网络上下载,这样不仅浪费流量又会影响用户体验,所以Android中引入了图片的缓存这一操作机制. 原理: 首先根据图片的网络地址在网络上下载图片,将图片先缓存到内存 ...

  5. DDoS攻防战(一):概述

    原文出处: 陶辉的博客   欢迎分享原创到伯乐头条 (此图摘自<Web脚本攻击与防御技术核心剖析>一书,作者:郝永清先生) DDoS,即 Distributed Denial of Ser ...

  6. winform 下log4net简单应用示例及“缺少log4net引用”的处理方案

    1.添加应用log4net.dll 2.新增log4net.config文件,文件内容如下 <?xml version="1.0" encoding="utf-8& ...

  7. [转]linux之nl命令

    转自:http://www.cnblogs.com/peida/archive/2012/11/01/2749048.html nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容 ...

  8. 链表回文串判断&&链式A+B

    有段时间没有练习了,链表回文串判断用到了栈.链式A+B将没有的项用0补充.链表有没有头节点,及结点和链表的区别,即pNode和pHead. //#include<iostream> //u ...

  9. C使用FILE指针文件操作

    文件的基本概念 所谓“文件”是指一组相关数据的有序集合. 这个数据集有一个名称,叫做文件名.实际上在前面的各章中我们已经多次使用了文件,例如源程序文件.目标文件.可执行文件.库文件 (头文件)等.文件 ...

  10. gradle使用eclipse debug 代码

    设置环境变量 unix,linux      export GRADLE_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=9999,s ...