首先

我们考虑每次船来回运人时都可以看成一种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. const放在函数前后的区别

    转载:const放在函数前后的区别 一.const修饰指针 int b = 500; 1.const int * a = & b; 2.int const * a = & b; 3.i ...

  2. STM32之旅4——USART

    STM32之旅4--USART 串口也是用的比较多的,在STM32CubeMX中生成代码后,需要添加一些代码才可以用. drv_usart.h: #ifndef __DRV_USART_H #defi ...

  3. ansible-playbook通过github拉取部署Lnmp环境

    1. 配置服务器初始化  1.1) 关闭防火墙和selinux 1 [root@test-1 ~]# /bin/systemctl stop firewalld 2 [root@test-1 ~]# ...

  4. 你还在手撕微服务?快试试 go-zero 的微服务自动生成

    0. 为什么说做好微服务很难? 要想做好微服务,我们需要理解和掌握的知识点非常多,从几个维度上来说: 基本功能层面 并发控制&限流,避免服务被突发流量击垮 服务注册与服务发现,确保能够动态侦测 ...

  5. CSS的背景

    CSS的背景 1. 背景颜色background-color div { background-color: 颜色值; } 一般情况下元素背景颜色默认是transparent(透明). 2. 背景图片 ...

  6. laravel重写

    laravel location / { try_files $uri $uri/ /index.php?$query_string; } ci location / { try_files $uri ...

  7. CentOS 6编译安装Redis

    [root@localhost ~]# vim /etc/sysconfig/iptables # 添加如下:-A INPUT -m state –state NEW -m tcp -p tcp –d ...

  8. 自动化遍历-appcrawler

    下载appclawler 下载地址:https://pan.baidu.com/s/1dE0JDCH#list/path=%2F 查看帮助文档: java -jar appcrawler-2.4.0- ...

  9. Hugo+Github 搭建个人博客(Windows环境下)

    目录 Hugo+Github 搭建个人博客(Windows环境下) 1.前言 2.Differences 2.1 https vs SSH 2.2 新建的github的仓库名必须为 用户名+githu ...

  10. java 保留小数点后指定位数四种方法

    1 package com.itheima_01; 2 3 import java.math.BigDecimal; 4 import java.text.DecimalFormat; 5 impor ...