SGU 221.Big Bishops(DP)

时间:2023-03-09 21:34:10
SGU 221.Big Bishops(DP)

题意:

给一个n*n(n<=50)的棋盘,放上k个主教(斜走),求能放置的种类总数。


Solution :

SGU 220,加个高精度就好了。

code

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std; string f[][][], ans;
int tem[];
int n, k, tol; string add (string a, string b) {
string c;
int s[] = {};
for (int i = ; i < a.size(); i++) s[i] += a[i] - '';
for (int i = ; i < b.size(); i++) s[i] += b[i] - '';
int len = max (a.size(), b.size() );
for (int i = ; i < len; ++i) {
if (s[i] >= ) {
s[i + ] += s[i] / , s[i] = s[i] % ;
if (i + == len) len++;
}
c += '' + s[i];
}
return c;
}
string operator * (string a, int k) {
string c;
int len = a.size(), x = ;
for (int i = , tem; i < len; ++i) {
tem = (a[i] - '') * k + x;
c += '' + tem % ;
x = tem / ;
}
for (; x; x /= ) c += '' + x % ;
return c;
}
string operator * (string a, string b) {
string c;
int s[] = {};
for (int i = ; i < a.size(); ++i)
for (int j = ; j < b.size(); ++j)
s[i + j] += (a[i] - '') * (b[j] - '');
int len = a.size() + b.size() - ;
for (int i = ; i < len; ++i) {
if (s[i] >= ) {
s[i + ] += s[i] / , s[i] %= ;
if (i + == len) len++;
}
c += '' + s[i];
}
return c;
}
void make (int x) {
tol = ;
for (int t = x; t <= n; t += ) {
tem[++tol] = t;
if (t != n) tem[++tol] = t;
}
f[x - ][][] = "";
string t;
for (int i = ; i <= tol; i++)
for (int j = ; j <= k; j++)
if (tem[i] >= j) {
if (j > ) t = f[x - ][i - ][j - ] * (tem[i] - j + );
else t = "";
f[x - ][i][j] = add (f[x - ][i - ][j] , t );
}
}
int main() {
ios::sync_with_stdio ();
cin >> n >> k;
make ();
make ();
ans = "";
for (int i = ; i <= k; i++)
ans = add (ans , f[][tol][i] * f[][ * n - - tol][k - i]);
while (* (ans.end() - ) == '' && ans.size() > ) ans.erase (ans.end() - );
reverse (ans.begin(), ans.end() );
cout << ans ;
}