HDU2157How many ways??(DP)

本文介绍了一种使用动态规划(DP)解决特定图论问题的方法:寻找从起点到终点经过固定数量景点的不同路径数目。通过定义状态dp[k][j]表示从起点到达j位置并经过k个景点的路径数,利用状态转移方程实现有效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给你一张道路情况的无权有向图,请你找出从a到b中途经过k个旅游景点的道路方案数,并且结果要模除1000。

解题思路:本题之前有做过一个类似的,只不过所求的解不同,那题是求最短路。这题则是用DP,设状态dp[k][j]表示从起点到达j位置,并且中途经过k个旅游景点的方案数,则状态转移方程:dp[k][z]=(dp[k][z]+dp[k-1][j])%1000,解释:从起点到达终点如果可以直接到达就为1,这里要初始化边界dp[0][b]=1,表示不用经过任何景点就能到达,状态转移就是从中插1个,然后2个,然后...最终到达最优解。并且在写转移方程要注意的点是:当起点j和终点z连通,才能够增加方法数,类似于分步乘法的组合数原理,每次多一种路的情况把之前的方法数加上来。(好吧我也不知道在讲啥了,思路有点乱,看代码吧,我想说得是你要知道终点和起点方法数的转移这点就对了)这里之前写有个bug,想当然地想打表减少复杂度,但是始终不知道在起点不同的情况下怎么处理,然后就英勇的gg了。

AC代码如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=21;

int dp[maxn][maxn],map[maxn][maxn];

int main()
{
    int i,j,s,z,a,b,k,n,m;
    while(~scanf("%d%d",&n,&m) && n+m)
    {
        memset(map,0,sizeof(map));
        //无向图构建
        for(i=0;i<m;i++)
        {
            cin>>a>>b;
            map[a+1][b+1]=1;
        }
        cin>>s;
        while(s--)
        {
            memset(dp,0,sizeof(dp));
            scanf("%d%d%d",&a,&b,&k);
            dp[0][a+1]=1;
            for(i=1;i<=k;i++)
            {
                for(j=1;j<=n;j++)
                    for(z=1;z<=n;z++)
                        if(map[j][z])
                        {
                            dp[i][z]=(dp[i-1][j]+dp[i][z])%1000;
                        }
            }
            cout<<dp[k][b+1]<<endl;
        }
    }
    return 0;
}

好像网上的题解大多是矩阵快速幂的解法QAQ
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值