Description
有一个载重为
k
千克的船,现在有
Input
第一行两个整数
n,k
表示人数和载重量,之后输入
n
个整数表示每个人的体重,要么
Output
如果有方案可以使得所有人可以过河则输出船来回的最少次数以及方案数,结果模 109+7 ,若无解则来回次数输出为 −1 ,方案数输出 0
Sample Input
1 50
50
Sample Output
1
1
Solution
以
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=55;
#define mod 1000000007
int n,k,C[maxn][maxn],dis[maxn][maxn][2],dp[maxn][maxn][2];
struct node
{
int x,y,z;
};
void add(int &x,int y)
{
x=x+y>=mod?x+y-mod:x+y;
}
int main()
{
C[0][0]=1;
for(int i=1;i<=50;i++)
{
C[i][0]=C[i][i]=1;
for(int j=1;j<i;j++)add(C[i][j],C[i-1][j-1]+C[i-1][j]);
}
scanf("%d%d",&n,&k);
int n0=0,n1=0;
while(n--)
{
int temp;
scanf("%d",&temp);
if(temp==50)n0++;
else n1++;
}
memset(dis,-1,sizeof(dis));
dis[n0][n1][0]=0,dp[n0][n1][0]=1;
queue<node>que;
que.push((node){n0,n1,0});
while(!que.empty())
{
node now=que.front();
que.pop();
int x=now.x,y=now.y,z=now.z;
for(int i=0;i<=x;i++)
{
if(i*50>k)break;
for(int j=0;j<=y;j++)
{
if(i+j==0)continue;
if(i*50+j*100>k)break;
int xx=n0-x+i,yy=n1-y+j,zz=1-z;
if(dis[xx][yy][zz]==-1)
{
dis[xx][yy][zz]=dis[x][y][z]+1;
dp[xx][yy][zz]=(ll)dp[x][y][z]*C[x][i]%mod*C[y][j]%mod;
que.push((node){xx,yy,zz});
}
else if(dis[xx][yy][zz]==dis[x][y][z]+1)
add(dp[xx][yy][zz],(ll)dp[x][y][z]*C[x][i]%mod*C[y][j]%mod);
}
}
}
printf("%d\n%d\n",dis[n0][n1][1],dp[n0][n1][1]);
return 0;
}