[Topcoder]AvoidRoads(dp,hash)

题目连接:https://community.topcoder.com/stat?c=problem_statement&pm=1889&rd=4709

题意:给一张n*m的地图,上面有些路不能走,每次只能向左走或者向下走。问从(0,0)走到(n,m)一共有多少种走法。

动态规划,先哈希标记出所有无法走的道路,然后做DP。

转移方程:

如果(i-1,j)可以走到(i,j):dp(i,j)+=dp(i-1,j)

如果(i,j-1)可以走到(i,j):dp(i,j)+=dp(i,j-1)

 1 // BEGIN CUT HERE
 2 
 3 // END CUT HERE
 4 #line 5 "AvoidRoads.cpp"
 5 #include <cstdlib>
 6 #include <cctype>
 7 #include <cstring>
 8 #include <cstdio>
 9 #include <cmath>
10 #include <algorithm>
11 #include <vector>
12 #include <string>
13 #include <iostream>
14 #include <sstream>
15 #include <map>
16 #include <set>
17 #include <queue>
18 #include <stack>
19 #include <fstream>
20 #include <numeric>
21 #include <iomanip>
22 #include <bitset>
23 #include <list>
24 #include <stdexcept>
25 #include <functional>
26 #include <utility>
27 #include <ctime>
28 using namespace std;
29 
30 typedef long long ll;
31 const int mod = 1000007;
32 bool cut[mod];
33 unsigned long long dp[130][130];
34 
35 int cv(int x1, int y1, int x2, int y2) {
36     return ((((x1 * 1007 % mod) + y1 * 737 % mod) + x2 * 103) % mod + y2 * 71) % mod;
37 }
38 
39 class AvoidRoads
40 {
41         public:
42         long long numWays(int width, int height, vector<string> bad) {
43             int x1,y1,x2,y2;
44             int& n = width;
45             int& m = height;
46             memset(cut, 0, sizeof(cut));
47             memset(dp, 0, sizeof(dp));
48             for(int i = 0; i < bad.size(); i++) {
49                 stringstream ss;
50                 ss << bad[i];
51                 ss >> x1 >> y1 >> x2 >> y2;
52                 cut[cv(x1,y1,x2,y2)] = 1;
53                 cut[cv(x2,y2,x1,y1)] = 1;
54 
55             }
56             dp[0][0] = 1;
57             for(int i = 0; i < n; i++) {
58                 if(!cut[cv(i,0,i+1,0)]) dp[i+1][0] = dp[i][0];
59                 else break;
60             }
61             for(int i = 0; i < m; i++) {
62                 if(!cut[cv(0,i,0,i+1)]) dp[0][i+1] = dp[0][i];
63                 else break;
64             }
65             for(int i = 1; i <= n; i++) {
66                 for(int j = 1; j <= m; j++) {
67                     if(!cut[cv(i-1,j,i,j)]) dp[i][j] += dp[i-1][j];
68                     if(!cut[cv(i,j-1,i,j)]) dp[i][j] += dp[i][j-1];
69                 }
70             }
71             return dp[n][m];
72         }
73         
74 // BEGIN CUT HERE
75     public:
76     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
77     private:
78     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); }
79     void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << Received << '"' << endl; } }
80     void test_case_0() { int Arg0 = 6; int Arg1 = 6; string Arr2[] = {"0 0 0 1","6 6 5 6"}; vector <string> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 252LL; verify_case(0, Arg3, numWays(Arg0, Arg1, Arg2)); }
81     void test_case_1() { int Arg0 = 1; int Arg1 = 1; string Arr2[] = {}; vector <string> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 2LL; verify_case(1, Arg3, numWays(Arg0, Arg1, Arg2)); }
82     void test_case_2() { int Arg0 = 35; int Arg1 = 31; string Arr2[] = {}; vector <string> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 6406484391866534976LL; verify_case(2, Arg3, numWays(Arg0, Arg1, Arg2)); }
83     void test_case_3() { int Arg0 = 2; int Arg1 = 2; string Arr2[] = {"0 0 1 0", "1 2 2 2", "1 1 2 1"}; vector <string> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); long long Arg3 = 0LL; verify_case(3, Arg3, numWays(Arg0, Arg1, Arg2)); }
84 
85 // END CUT HERE
86 
87 };
88 
89 // BEGIN CUT HERE
90 int main()
91 {
92         AvoidRoads ___test;
93         ___test.run_test(-1);
94         return 0;
95 }
96 // END CUT HERE
原文地址:https://www.cnblogs.com/kirai/p/5607347.html