題目大意:,給定n個點形成環,中間一個點0,每個點到0連一條邊,問從0開始,經過m條邊有多少條路徑使得回到0點,每個點每條邊都可以經過多次。
輸出路徑數
思路:這個題目如果不考慮資料規模的話,用矩陣乘法可以解這個題,詳見矩陣的十種應用,那個適用於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]);}}}