SGU 407-Number of Paths in the Empire【DP】

题目大意:如图,给定n个点形成环,中间一个点0,每个点到0连一条边,问从0开始,经过m条边有多少条路径使得回到0点,每个点每条边都可以经过多次。SGU 407-Number of Paths in the Empire【DP】_第1张图片

输出路径数

思路:这个题目如果不考虑数据规模的话,用矩阵乘法可以解这个题,详见矩阵的十种应用,那个适用于100个点的任意图。

这个题n<=1000,m<=5000 不可,所以我想到了一个dp方法,dp[i][j]表示i步到j的方案数,转移就好说了。时间复杂度似乎也是可以解决的。

这个题并没有把结果取余,哎,这样的话,答案就是个好几千位的数了。囧。。。时间复杂度还得算上两个数相加的时间!!!果断超内存超时。

然后我就想到了一个一维的dp。dp[i][0]表示i步到0的方案数,dp[i][1]表示i步到非0的方案数。

转移为:dp[i+1][0] += dp[i][1];
              dp[i+1][1] += dp[i][0]*n + dp[i][1] * 2;


这样的话,题目就简单了。

我偷懒写的java。

code:

import java.util.*;
import java.math.*;
public class Solution
{
	public static void main(String args[])
	{
		BigInteger dp[][]=new BigInteger[5010][2];
		int n,m;
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext())
		{
			n=sc.nextInt();
			m=sc.nextInt();
			for(int i=0;i<=m;i++)
				for(int j=0;j<2;j++)
					dp[i][j]=BigInteger.ZERO;
			dp[0][0]=BigInteger.ONE;
			for(int i = 0;i < m;i++)
		    {
		        dp[i+1][0]=dp[i+1][0].add( dp[i][1]) ;
		        BigInteger t=new BigInteger(Integer.toString(n));
		        t=t.multiply(dp[i][0]);
		        dp[i+1][1]=dp[i+1][1].add(t) ;
		        dp[i+1][1]=dp[i+1][1].add(dp[i][1]) ;
		        dp[i+1][1]=dp[i+1][1].add(dp[i][1]) ;
		    }
			System.out.println(dp[m][0]);
		}
	}
}

你可能感兴趣的:(SGU 407-Number of Paths in the Empire【DP】)