CF295C Greg and Friends
首先
我们考虑每次船来回运人时都可以看成一种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的更多相关文章
- Codeforces 295A Greg and Array
传送门 A. Greg and Array time limit per test 1.5 seconds memory limit per test 256 megabytes input stan ...
- 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 ...
- Codeforces Round #156 (Div. 2)---A. Greg's Workout
Greg's Workout time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- 那些年我们写过的三重循环----CodeForces 295B Greg and Graph 重温Floyd算法
Greg and Graph time limit per test 3 seconds memory limit per test 256 megabytes input standard inpu ...
- Codeforces 295C Greg and Friends BFS
Greg and Friends BFS的过程中维护一下方案数. 我个人感觉不是很好想, 但是写出来之后怎么感觉这题这么SB啊啊. #include<bits/stdc++.h> #def ...
- Codeforces 295 B. Greg and Graph
http://codeforces.com/problemset/problem/295/B 题意: 给定一个有边权的有向图.再给定一个1~n的排列. 按排列中的顺序依次删除点,问每次删除后,所有点对 ...
- 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 ...
- Greg and Array CodeForces 296C 差分数组
Greg and Array CodeForces 296C 差分数组 题意 是说有n个数,m种操作,这m种操作就是让一段区间内的数增加或则减少,然后有k种控制,这k种控制是说让m种操作中的一段区域内 ...
- ACM - 最短路 - CodeForces 295B Greg and Graph
CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...
随机推荐
- Java知识系统回顾整理01基础03变量06变量的作用域
一.变量根据所处的位置对应不同的名称 变量处于不同的位置,有不同的名称 名称分别是 字段,属性 参数 局部变量 不同名称的变量,其作用域是不一样的 二.字段,属性,Field 当一个变量被声明在类下 ...
- C++中memset函数的用法
转载:https://blog.csdn.net/qq_22122811/article/details/52738029 //复习数组的时候,第一次见到了memset,学之. memset:char ...
- 给Python IDLE添加行号显示
转载:https://blog.csdn.net/howard2005/article/details/104112297 文章目录一.引出问题1.Spyder编辑Python程序能显示行号2.Pyt ...
- Arduino control Eeprom by IIC method of using device address in Arduino
参考: 1.https://www.arduino.cc/ 2.https://www.arduino.cc/reference/en/ 3.https://www.arduino.cc/en/Ref ...
- C/C++ 中 exit() 函数
参考: https://blog.csdn.net/jjjcainiao/article/details/21935795 知乎上的问题]C/C++ 中 exit() 函数的参数到底有什么意义? C ...
- P4454 [CQOI2018]破解D-H协议
链接 这题并不难只是需要把题读懂 - By ShadderLeave 一句话题意 给定两个数 \(p\)和\(g\),有\(t\)组询问,每组询问给出\(A\)和\(B\) 其中 A = \(g^a ...
- Android使用Mono c#分段列表视图
下载source code - 21.7 KB 你想知道如何把多个ListView控件放到一个布局中,但是让它们在显示时表现正确吗 多个列表项?你对它们正确滚动有问题吗?这个例子将向你展示如何组合单独 ...
- 二进制部署Redis-5.07
Redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理. 它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类 ...
- c#之task与thread区别及其使用
如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...
- C# 主界面的扁平化
如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...