標籤:style blog http color io os 使用 ar for
題目連結:http://poj.org/problem?id=2346
思路:
使用動態規劃解法:
設函數 d( n, x )代表長度為n且滿足左邊n/2位的和減去右邊n/2位的和為x的數的數目。
將一個長度為n的數看做n個數字 A1, A2....An ( 0 <= Ai <= 9 ),將字元分為兩個集合{ A1, A2....An/2 } 與 { An/2+1.....An };
問題轉換為求集合中元素和相等的數目。先從每個集合中選出一個元素,求它們差為a的可能數目,即d( 2, a );
再求兩個集合剩下的元素和的差為 x - a 的數目,即d( n -2, x -a );所以動態遞迴方程為 d( n, x ) = ∑ d( n - 2, x - a ) * d( 2, a ); (-9<=a<=9)
可以使用記憶搜尋求解。
代碼:
#include <stdio.h>#include <math.h>#include <string.h>const int MAX_N = 11;int dp[MAX_N][MAX_N];int d( int n, int x ){ if ( dp[n][x] != -1 ) return dp[n][x]; if ( n == 2 ) { int sum = 0; for ( int a = 0; a <= 9; ++a ) for ( int b = 0; b <= 9; ++b ) if (a - b == x) sum++; return dp[n][x] = sum; } else { int a, b, sum = 0; for ( b = -9; b <= 9; ++b ) { a = x - b; if (a >= -9 * (n - 2) / 2 && a <= 9 * (n - 2) / 2) sum += d(n - 2, abs(a)) * d(2, abs(b) ); } return dp[n][x] = sum; } }int main(){ int n; long long ans = 0; memset(dp, -1, sizeof(dp)); scanf("%d", &n); ans = d(n, 0); printf("%lld\n", ans); return 0;}
poj 2346 Lucky tickets