10.29
最近刷leetcode刷的有点膨胀了
点开web Arena做第一题AB,瞬间AC,卧槽我宝刀未老!
点开一个550、卧槽。。
点开一个850、卧槽草草草。。
弄好了Arena 准备起飞
850的题目是 问N个节点(各不相同)的图,有多少有座桥。
今天做了一题,POJ1737
我又用了一种乱七八糟的方法,我也是醉了
#include<iostream> #include<algorithm> #include<map> #include<unordered_map> #include<vector> #include<string> #include<stack> #include<queue> using namespace std; const int MaxN = 50; int main() { vector<long long> f = vector<long long>(MaxN + 1, 0); vector<vector<long long>> g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); vector<vector<long long>> c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); c[0][0] = 1; for (int i = 1; i <= MaxN; i++) { c[i][0] = c[i][i] = 1; for (int j = 1; j <= i-1; j++) c[i][j] = c[i - 1][j] + c[i - 1][j - 1]; } // g[0][0] = 1; // f[1] = 1; for (int n = 2; n <= MaxN; n++) { //g[n-1,n-1] for (int k = 1; k <= n - 1; k++) { for (int s1 = 1; s1 <= n - 1; s1++) g[n - 1][k] += ((1 << s1) - 1)*f[s1] * c[n - 2][s1 - 1] * g[n - 1 - s1][k - 1]; f[n] += g[n - 1][k]; } } int X; while (cin >> X) { if (!X) break; cout << f[X] << endl; } return 0; }
这当然是过不了了。。时间复杂度比较高,然后高精度也没有上。
不过意思到了就行了
我想的是 1连的那个连通分支有哪些点,用dp套一个dp
看了别人的解答:
设f(n)为所求答案
g(n)为n个顶点的非联通图
则f(n) + g(n) = h(n) = 2^(n * (n - 1) / 2)
其中h(n)是n个顶点的联图的个数
这样计算
先考虑1所在的连通分量包含哪些顶点
假设该连通分量有k个顶点
就有C(n - 1, k - 1)种集合
确定点集后,所在的连通分量有f(k)种情况。其他连通分量有 h(n - k)种情况
因此有递推公式。g(n) = sum{ C(n - 1, k - 1) * f(k) * h(n - k)} 其中k = 1,2...n-1
注意每次计算出g(n)后立刻算出f(n)
好吧 我那个做法也许是有一些借鉴意义的。。毕竟。。难想到。。
11.8
先贴一个小数据版本的,妈蛋为了搞这个一晚上没有玩多塔
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<map> #include<unordered_map> #include<vector> #include<string> #include<stack> #include<queue> using namespace std; const int MaxN = 15; const long long Modulo = 1000000007; vector<vector<long long>> calcComb() { vector<vector<long long>> c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); c[0][0] = 1; for (int i = 1; i <= MaxN; i++) { c[i][0] = c[i][i] = 1; for (int j = 1; j <= i - 1; j++) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % Modulo; } return c; } long long pow(int s1, int c) { long long ret = 1; while (c--) ret *= s1; return ret; } int main() { auto C = calcComb(); //calc f1[n] : n nodes with 1 component auto f1 = vector<long long>(MaxN + 1, 0); auto g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); g[0][0] = 1; f1[1] = 1; for (int n = 2; n <= MaxN; n++) { for (int c = 1; c <= n - 1; c++) // c components { for (int s1 = 1; s1 <= n - 1; s1++) g[n - 1][c] += ((1 << s1) - 1) * f1[s1] * C[n - 2][s1 - 1] * g[n - 1 - s1][c - 1]; f1[n] += g[n - 1][c]; } } //f2[n]: n nodes with no bridge auto f2 = vector<long long>(MaxN + 1, 0); g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); g[0][0] = 1; f2[0] = 1; for (int n = 1; n <= MaxN; n++) { f2[n] = f1[n]; for (int c = 1; c <= n - 1; c++) { for (int s1 = 1; s1 <= n - 1; s1++) g[n - 1][c] += (s1 * C[n - 2][s1 - 1] * f1[s1] * g[n - 1 - s1][c - 1]); } for (int s1 = 1; s1 <= n - 1; s1++) { for (int c = 1; c <= n - 1;c++) f2[n] -= (C[n - 1][s1 - 1] * f2[s1] * /*/ 激动的快哭了,找到个bug的时候,没有乘 /*/pow(s1,c) * g[n - s1][c]); } } auto f3 = vector<vector<long long>>(MaxN + 1,vector<long long>(MaxN + 1,0)); //f3[n][k] n nodes k bridges f3[0][0] = 1; auto gg = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0))); gg[0][0][0] = 1; for (int n = 1; n <= MaxN; n++) { f3[n][0] = f2[n]; for (int k = 1; k <= MaxN; k++) { for (int c = 1; c <= n - 1;c++) for (int n1 = 1; n1 <= n - 1;n1++) for (int k1 = 0; k1 < k; k1++) { gg[n - 1][k][c] += n1 * C[n-2][n1-1] * f3[n1][k1] * gg[n - 1 - n1][k - k1 - 1][c - 1]; } for (int n1 = 1; n1 <= n - 1; n1++) { for (int c = 1; c <= n; c++) f3[n][k] += C[n - 1][n1 - 1] * f2[n1] * /*还TM漏一个*/pow(n1,c) * gg[n - n1][k][c]; } } } auto f4 = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0))); f4[0][0][0] = 1; for (int n = 1; n <= MaxN; n++) for (int k = 0; k < MaxN; k++) { f4[n][k][1] = f3[n][k]; for (int c = 2; c <= MaxN; c++) { for (int n1 = 1; n1 <= n;n1++) for (int k1 = 0; k1 <= k; k1++) f4[n][k][c] += f3[n1][k1] * C[n - 1][n1 - 1] * f4[n - n1][k - k1][c-1]; } } int n, k; while (cin >> n >> k) { int ret = 0; for (int c = 1; c <= n; c++) ret += f4[n][k][c]; cout << ret << endl; } system("pause"); return 0; }
再来一个超时版本的O(N^5)
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<map> #include<unordered_map> #include<vector> #include<string> #include<stack> #include<queue> using namespace std; const int MaxN = 50; const long long M = 1000000007; long long mul(long long A, long long B) { return (A % M) * (B % M) % M; } void adt(long long& x, long long a) { x = (x + a) % M; } vector<vector<long long>> calcComb() { auto c = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); c[0][0] = 1; for (int i = 1; i <= MaxN; i++) { c[i][0] = c[i][i] = 1; for (int j = 1; j <= i - 1; j++) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % M; } return c; } vector<vector<long long>> calcPow() { auto p = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); for (int i = 1; i <= MaxN; i++) { p[i][0] = 1; for (int j = 1; j <= MaxN; j++) p[i][j] = mul(i,p[i][j-1]); } return p; } int main() { auto C = calcComb(); auto POW = calcPow(); //calc f1[n] : n nodes with 1 component auto f1 = vector<long long>(MaxN + 1, 0); auto g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); g[0][0] = 1; f1[1] = 1; for (int n = 2; n <= MaxN; n++) { for (int c = 1; c <= n - 1; c++) // c components { for (int s1 = 1; s1 <= n - 1; s1++) g[n - 1][c] += mul(mul(mul((pow(2,s1) - 1),f1[s1]),C[n - 2][s1 - 1]),g[n - 1 - s1][c - 1]); adt(f1[n],g[n - 1][c]); } } //f2[n]: n nodes with no bridge auto f2 = vector<long long>(MaxN + 1, 0); g = vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0)); g[0][0] = 1; f2[0] = 1; for (int n = 1; n <= MaxN; n++) { f2[n] = f1[n]; for (int c = 1; c <= n - 1; c++) { for (int s1 = 1; s1 <= n - 1; s1++) adt(g[n - 1][c],mul(mul(mul(s1, C[n - 2][s1 - 1]),f1[s1]),g[n - 1 - s1][c - 1])); } for (int s1 = 1; s1 <= n - 1; s1++) { for (int c = 1; c <= n - 1;c++) adt(f2[n],M-mul(mul(mul(C[n - 1][s1 - 1],f2[s1]),/*/ 激动的快哭了,找到个bug的时候,没有乘 /*/POW[s1][c]),g[n - s1][c])); } } auto f3 = vector<vector<long long>>(MaxN + 1,vector<long long>(MaxN + 1,0)); //f3[n][k] n nodes k bridges f3[0][0] = 1; auto gg = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0))); gg[0][0][0] = 1; for (int n = 1; n <= MaxN; n++) { f3[n][0] = f2[n]; for (int k = 1; k <= MaxN; k++) { for (int c = 1; c <= n - 1;c++) for (int n1 = 1; n1 <= n - 1;n1++) for (int k1 = 0; k1 < k; k1++) { adt(gg[n - 1][k][c],mul(mul(mul(n1,C[n-2][n1-1]),f3[n1][k1]),gg[n - 1 - n1][k - k1 - 1][c - 1])); } for (int n1 = 1; n1 <= n - 1; n1++) { for (int c = 1; c <= n; c++) adt(f3[n][k],mul(mul(mul(C[n - 1][n1 - 1],f2[n1]), /*还TM漏一个*/POW[n1][c]),gg[n - n1][k][c])); } } } auto f4 = vector<vector<vector<long long>>>(MaxN + 1, vector<vector<long long>>(MaxN + 1, vector<long long>(MaxN + 1, 0))); f4[0][0][0] = 1; for (int n = 1; n <= MaxN; n++) for (int k = 0; k < MaxN; k++) { f4[n][k][1] = f3[n][k]; for (int c = 2; c <= MaxN; c++) { for (int n1 = 1; n1 <= n;n1++) for (int k1 = 0; k1 <= k; k1++) adt(f4[n][k][c],mul(mul(f3[n1][k1],C[n - 1][n1 - 1]),f4[n - n1][k - k1][c-1])); } } int n, k; while (cin >> n >> k) { long long ret = 0; for (int c = 1; c <= n; c++) adt(ret,f4[n][k][c]); cout << ret << endl; } system("pause"); return 0; }