首页 > 试题广场 >

黄油运输的迷思(三)

[编程题]黄油运输的迷思(三)
  • 热度指数:107 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

当智加科技的无人驾驶车队首次进行横跨美洲的生鲜运输时,工程师阳阳注视着一桶桶的黄油陷入了沉思。他突发奇想,要这一切都是标准化包装物件,那么其尺寸不仅节约控件、提升干线物流运输效率,同时也让简化车辆的动力学、运动学建模,帮助自动驾驶算法更精准、灵敏地操控车辆(但愿如此)。
如果现有两种包装物品的包装运输箱,尺寸分别是长宽 1米×1米 和 1米×2米。

  • 假定用这两种箱子排成一片 m列n行 (m米×n米) 的阵列,不限两种箱子的使用数量(注意:1米×2米 箱子不能旋转方向使用,即不能作为 2米×1米 的箱子跨列摆放在阵列中);

  • 【本题编程】在此基础上,若我们限制箱子阵列必须存在交错排列,以确保货物在运输过程中稳定,则有多少种不同的排列方式?
    注意:对于一个 m米×n米 的阵列,交错排列的定义是:不存在行方向上的某一个位置 k米处 (1<k<n) 可以沿着箱子之间的缝隙将阵列完全
    分离成 m米×k米 和 m米×(n-k)米 两个阵列。


输入描述:
第一行输入为 整数 m (1<=m<=10)
第二行输入为 整数 n (1<=n<=10)


输出描述:
第一行输出为结果整数
示例1

输入

2
2

输出

3

动态规划

这次的数据范围相比前两次迷思小了很多,斐波那契数列可以用递推的方式来求。主要的思路就是用“黄油运输的迷思(二)”的结果减去存在缝隙的排列数。
m = int(input())
n = int(input())
# 不考虑缝隙的排列方案数
dp = [0] * 11
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):
    dp[i] = dp[i - 2] + dp[i - 1]
# 考虑缝隙的排列方案数
dp2 = [0] * 11
for i in range(1, n + 1):
    dp2[i] = dp[i]**m      # 先初始化为不考虑缝隙的方案数
    # 枚举缝隙,将有缝隙的方案减掉
    for j in range(1, i):
        dp2[i] -= dp2[j] * dp[i - j]**m
print(dp2[n])
这里解释一下dp2数组,dp2[i]表示将黄油排列成m*i规模的阵列有多少种交错的方案。将其初始化为不考虑存在缝隙的方案数,然后枚举缝隙位置,把有缝隙的方案去掉。
编辑于 2022-04-08 16:14:05 回复(0)
此题目为高精,c++不提供高精....所以以下代码都无法完全通过。
我们知道只有一行箱子的排列方案是斐波那契数列f[n]。
f[0]=f[1]=1;
for(i=2;i<=n;i++)
    f[i]=f[i-1]+f[i-2];
如果是m行n列矩阵的时候方案数是dp[n]=f[n]^m
for(i=1;i<=n;i++)
{
  dp[i]=1;
  for(j=1;j<=m;j++)
    dp[i]*=f[i];
}
再加上不存在缝隙这个条件,可以用总方案数-存在缝隙方案数。
此处用dp2[n]表示这个方案数
那么存在缝隙的方案怎么算?例如n=5,那么缝隙会把整个n分割成多个部分
例如5=1+4,表示一个1*m的矩阵和4*m的矩阵,两矩阵中间有一个缝隙,并且这两个矩阵都不存在缝隙。
这样求缝隙就转换为一个dfs求n的所有和排列的方法。
#include <bits/stdc++.h>//ASI
typedef long long ll;
using namespace std;
ll n,m,tt,f[105],dp[105],dp2[105],sum=0,a[15];
void dfs(int all,int t)
{
    int i;
    if(all==tt)
    {
        ll s=1;
        for(i=1;i<t;i++)
            s*=dp2[a[i]];
        sum+=s;
    }
    for(i=1;i<tt;i++)
    {
        if((all+i)>n)
            return ;
        a[t]=i;
        dfs(all+i,t+1);
    }
}
int main()
{
    int i,j;
    cin>>m>>n;
    f[0]=f[1]=1;
    for(i=2;i<=n;i++)
        f[i]=f[i-1]+f[i-2];
    for(i=1;i<=n;i++)
    {
        dp[i]=1;
        for(j=1;j<=m;j++)
            dp[i]*=f[i];
    }
    dp2[1]=1;
    for(i=2;i<=n;i++)
    {
        tt=i;
        sum=0;
        dfs(0,1);
        dp2[i]=dp[i]-sum;
    }
    cout<<dp2[n];
    return 0;
}




发表于 2021-03-16 16:03:04 回复(0)

热门推荐

通过挑战的用户