首先

我们考虑每次船来回运人时都可以看成一种dp状态

又因为人的体重只有50kg和100kg两种,

所以我们可以开一个三维数组dp[i][j][k],第1维表示在出发岸50kg有i个,第2维表示在出发岸100kg有j个,第3维表示船在哪一岸

又考虑到每一个人都是不同的,所以我们需要对在船岸的这一边的人数和上船的人数去组合数,可以打一个杨辉三角的表b[i][j],用来快速查询组合数

所以状态转移就可以枚举在此岸上船50kg和100kg的人数并取组合数乘上自己的原值(乘法原理)

其次

本题还要求求最短运送次数,我们就可以用广搜来遍历枚举答案

同理dp的状态转移也可以在广搜中一起完成

#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct kk
{
ll i,j,k;
}sh[1000001];//数组模拟队列
ll n,w,step[100][100][3],dp[100][100][3];
ll a[100],t50,t100,b[1000][1000],mod;
void bfs(ll i1,ll j1,ll wh)
{
ll l,r;
l=0;r=0;
sh[l].i=i1;
sh[l].j=j1;
sh[l].k=wh;
r++;
while (l<r)
{
ll nowi,nowj,nowh;
nowi=sh[l].i;
nowj=sh[l].j;
nowh=sh[l].k;
l++;
if (nowh==1)//枚举出发岸
for (ll x=0;x<=nowi;x++)
{
for (ll y=0;y<=nowj;y++)
{
if (50*x+100*y>w || (x==0 && y==0))
continue;//判断体重是否超过船载重
ll xi,xj,xwh;
xi=nowi-x;
xj=nowj-y;
xwh=1-nowh;
if (step[xi][xj][xwh]!=0)//重点,此处与一般的广搜不同,当一种状态被遍历过了不能直接标记掉,还要取最优情况
{
if (step[nowi][nowj][nowh]+1<step[xi][xj][xwh])
step[xi][xj][xwh]=step[nowi][nowj][nowh]+1;
if (step[nowi][nowj][nowh]+1==step[xi][xj][xwh])//步数相同时,更新dp值
{
dp[xi][xj][xwh]+=(b[nowi+1][x+1]%mod)*(b[nowj+1][y+1]%mod)*(dp[nowi][nowj][nowh]%mod);
dp[xi][xj][xwh]%=mod;
}
}
else
{
dp[xi][xj][xwh]=(b[nowi+1][x+1]%mod)*(b[nowj+1][y+1]%mod)*(dp[nowi][nowj][nowh]%mod);
dp[xi][xj][xwh]%=mod;
step[xi][xj][xwh]=step[nowi][nowj][nowh]+1;
sh[r].i=xi;
sh[r].j=xj;
sh[r].k=xwh;
r++;
}
}
}
if (nowh==0)//枚举对岸
for (ll x=0;x<=t50-nowi;x++)
{
for (ll y=0;y<=t100-nowj;y++)
{
if (50*x+100*y>w || (x==0 && y==0))
continue;
ll xi,xj,xwh;
xi=nowi+x;
xj=nowj+y;
xwh=1-nowh;
if (step[xi][xj][xwh]!=0)
{
if (step[nowi][nowj][nowh]+1<step[xi][xj][xwh])
step[xi][xj][xwh]=step[nowi][nowj][nowh]+1;
if (step[nowi][nowj][nowh]+1==step[xi][xj][xwh])
{
dp[xi][xj][xwh]+=(b[t50-nowi+1][x+1]%mod)*(b[t100-nowj+1][y+1]%mod)*(dp[nowi][nowj][nowh]%mod);
dp[xi][xj][xwh]%=mod;
}
}
else
{
dp[xi][xj][xwh]=(b[t50-nowi+1][x+1]%mod)*(b[t100-nowj+1][y+1]%mod)*(dp[nowi][nowj][nowh]%mod);
dp[xi][xj][xwh]%=mod;
step[xi][xj][xwh]=step[nowi][nowj][nowh]+1;
sh[r].i=xi;
sh[r].j=xj;
sh[r].k=xwh;
r++;
}
}
}
}
}
int main()
{
scanf("%lld%lld",&n,&w);
for (ll x=1;x<=n;x++)
scanf("%lld",&a[x]);
memset(dp,0,sizeof(dp));
memset(step,0,sizeof(step));
for (ll x=1;x<=n;x++)
{
if (a[x]==50)
t50++;
if (a[x]==100)
t100++;
}
b[1][1]=1;
for (ll x=2;x<=50;x++)
{
for (ll y=1;y<=x;y++)
b[x][y]=b[x-1][y]+b[x-1][y-1];//杨辉三角
}
mod=1000000007;
dp[t50][t100][1]=1;//令1表示出发岸,0表示到达岸
step[t50][t100][1]=0;//初始化
bfs(t50,t100,1);//广搜函数
if (step[0][0][0]==0)//如何到达的步数为0就不能到达
{
printf("-1\n");
printf("0\n");
}
else
{
printf("%lld\n",step[0][0][0]);//答案即为出发岸无人且船在对岸的情况
printf("%lld\n",dp[0][0][0]);
}
}

CF295C Greg and Friends的更多相关文章

  1. Codeforces 295A Greg and Array

    传送门 A. Greg and Array time limit per test 1.5 seconds memory limit per test 256 megabytes input stan ...

  2. Codeforces Round #179 (Div. 1) A. Greg and Array 离线区间修改

    A. Greg and Array Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/295/pro ...

  3. Codeforces Round #156 (Div. 2)---A. Greg&#39;s Workout

    Greg's Workout time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  4. 那些年我们写过的三重循环----CodeForces 295B Greg and Graph 重温Floyd算法

    Greg and Graph time limit per test 3 seconds memory limit per test 256 megabytes input standard inpu ...

  5. Codeforces 295C Greg and Friends BFS

    Greg and Friends BFS的过程中维护一下方案数. 我个人感觉不是很好想, 但是写出来之后怎么感觉这题这么SB啊啊. #include<bits/stdc++.h> #def ...

  6. Codeforces 295 B. Greg and Graph

    http://codeforces.com/problemset/problem/295/B 题意: 给定一个有边权的有向图.再给定一个1~n的排列. 按排列中的顺序依次删除点,问每次删除后,所有点对 ...

  7. codeforces 295C Greg and Friends(BFS+DP)

    One day Greg and his friends were walking in the forest. Overall there were n people walking, includ ...

  8. Greg and Array CodeForces 296C 差分数组

    Greg and Array CodeForces 296C 差分数组 题意 是说有n个数,m种操作,这m种操作就是让一段区间内的数增加或则减少,然后有k种控制,这k种控制是说让m种操作中的一段区域内 ...

  9. ACM - 最短路 - CodeForces 295B Greg and Graph

    CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...

随机推荐

  1. 山寨一个Spring的@Component注解

    1. 前言 我们在上一篇对Mybatis如何将Mapper接口注入Spring IoC进行了分析,有同学问胖哥这个有什么用,这个作用其实挺大的,比如让你实现一个类似@Controller的注解(或者继 ...

  2. 深入理解golang:Context

    一.背景 在golang中,最主要的一个概念就是并发协程 goroutine,它只需用一个关键字 go 就可以开起一个协程,并运行. 一个单独的 goroutine运行,倒也没什么问题.如果是一个go ...

  3. Centos7 Docker配置TLS认证的远程端口的证书生成教程(shell脚本一键生成)

    通过 TLS来进行远程访问 百度百科 - TLS.我们需要在远程 docker 服务器(运行 docker 守护进程的服务器)生成 CA 证书,服务器证书,服务器密钥,然后自签名,再颁发给需要连接远程 ...

  4. mac电脑上安装appium报错:Failed at the appium-chromedriver@4.25.1 postinstall script.

    mac电脑安装appium,装好node.js后,使用命令:npm install appium@1.18.0,安装appium,报如下错误 ``` ERR! errno1 ERR! appium-c ...

  5. Elasticsearch(4):映射

      ES中的映射(mapping)是用于定义索引中文档以及文档中的字段如何被存储和索引(动词)的一种机制,例如,通过映射我们可以进行如下的这些定义: 索引文档中,哪些字符型字段应该被当做全文本类型: ...

  6. CSS字体属性与文本属性

    CSS字体属性与文本属性 1. 字体属性 1.1 字体系列font-family p { font-family: "Microsoft Yahei";/*微软雅黑*/ } /*当 ...

  7. CSS常见反爬技术

    目录 利用字体 反爬原理 应对措施 难点: 利用背景 反爬原理 应对措施 利用伪类 反爬原理 应对措施 利用元素定位 反爬原理 应对措施 利用字符切割 反爬原理 应对措施 利用字体 反爬原理 反爬原理 ...

  8. idea创建servlet工程初体验

    servlet工程创建 前提:创建项目之前需要配置java环境变量 和tomcat配置,配置完成后进入如下操作. tomcat 安装和配置参考 https://www.cnblogs.com/xush ...

  9. kali 運行 chrome

    0x00前提 已經安裝好google chrome . 0x01 在終端執行命令: google-chrome,發現如圖: 錯誤提示:在root下只能使用 --no-sandbox選項來運行chrom ...

  10. Consul 学习笔记—服务发现

    前言: 上一篇文章简单实用Consul试下服务注册,本篇继续学习Consul中的另外特性:服务发现.KV操作 :以及对上篇文章中存在的问题进行解决 问题解决 在上一篇文章中,注册服务提示检查失败. 通 ...