這道題我是用偷懶的方法做的。在topcoder論壇上面看到大名鼎鼎的msg555也是用的這種方法,於是我就放心了。首先,用dfs跑n比較小的情況,可以跑到n=10,如果你足夠耐心的話,也可以得到更多結果。於是就有了下面的結果,對n=1~11:int arr = ; 在這之後就是找規律了。我是給系統發郵件)和**都可以得到生成函式,後者還可以以極短的時間算出來後續的序列(很好奇是如何做到的,還是高精度運算)。由於數學功底已經不如之前了,不知道如何從生成函式匯出遞推公式。但知道有遞推公式的存在,找到規律還是比較簡單的。
我們有:a[n] = 2 * a[n - 1] + 2 * a[n - 2] - 2 * a[n - 3] + a[n - 4]
之後就是如何根據這個遞推式匯出結果,及超過int的範圍怎麼辦(觀察增長速度,突破32位int是很快的事情)。
我用的是最*****的方法,寫了個1000位的加法和減法,然後把乘法當做多次加法(或減法)。於是就有了下面的解法:
user: chen chen [thestor1]task: vans
lang: c++
compiling...
compile: ok
executing...
test 1: test ok [0.008 secs, 3504 kb]
test 2: test ok [0.008 secs, 3504 kb]
test 3: test ok [0.003 secs, 3504 kb]
test 4: test ok [0.008 secs, 3504 kb]
test 5: test ok [0.005 secs, 3504 kb]
test 6: test ok [0.008 secs, 3504 kb]
test 7: test ok [0.005 secs, 3504 kb]
test 8: test ok [0.016 secs, 3504 kb]
test 9: test ok [0.032 secs, 3504 kb]
test 10: test ok [0.043 secs, 3504 kb]
test 11: test ok [0.057 secs, 3504 kb]
all tests ok.
/*
id: thestor1
lang: c++
task: vans
*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
const int maxn = 1000;
int n;
int dx = , dy = ;
bool isin(int r, int c)
vector> neighbors(int r, int c)
} return nbs;
}void dfs(vector> &visited, int r, int c, int cnt, int &total)
return;
} vector> nbs = neighbors(r, c);
int nr, nc;
for (int i = 0; i < nbs.size(); ++i) }
}void zero(std::vector&num)
}void assign(std::vector&lhs, std::vector&rhs)
}void add(std::vector&lhs, std::vector&rhs)
assert(carry == 0);
}void sub(std::vector&lhs, std::vector&rhs)
else
}assert (borrow == 0);
}void print(const std::vector&lhs)
for (int i = begin; i < lhs.size(); ++i)
cout << endl;
}int main()
; ofstream fout("vans.out");
fout << arr[n - 1] << endl;
fout.close();
return 0;
} // vector> visited(4, vector(n, false));
// int total = 0;
// dfs(visited, 0, 0, 0, total);
// a[n] = 2 * a[n - 1] + 2 * a[n - 2] - 2 * a[n - 3] + a[n - 4]
vector> a(5, vector(maxn, 0));
// a[0]
a[1][maxn - 1] = 2;
a[2][maxn - 1] = 4;
a[3][maxn - 2] = 1;
a[3][maxn - 1] = 2;
int a0 = 0, a1 = 1, a2 = 2, a3 = 3;
for (int i = 4; i < n; ++i)
ofstream fout("vans.out");
int begin = 0;
while (begin < maxn && a[4][begin] == 0)
for (int i = begin; i < a[4].size(); ++i)
fout << endl;
fout.close();
return 0;
}
USACO Hamming Codes 解題報告
資料小,暴力搜尋可以搞定。但是推薦使用dfs,每個節點 數 有取與不取兩個分支。注意 0是必須出現的。證明如下 最終得到的結果序列中,0是必須出現的,證明如下 如果存在另乙個滿足要求的結果序列s 其最小值為a1 n 0,那麼序列s s n 是滿足條件的最小解,且首元素為0 id xpli1 prog...
USACO Closed Fences 解題報告
幾何題看著就很有畏懼感。這裡用的是最 的演算法,時間複雜度應該在n 2。還沒看別人的解題報告,不過我猜nlogn的解法是有的。比如判斷乙個fence是不是valid的時候,這裡將所有的線段兩兩比較,看是否相交。但是有個叫line sweep的演算法,可以在nlogn的時間複雜度內完成。既然accep...
Wiggle Subsequence解題報告
這道題和最長子序列,divisible subset題目類似,都可以用o n2 的時間複雜度完成。可以想象,對於第i個數,dp i dp j 1,當且僅當dp j 1 dp i 而且nums j 和nums i 的差值和j所處位置的差值符號相反。所以,如下 class solution if dp ...