模拟 1001 Jam's math problem
判断b ^ 2 - 4ac是否为完全平方数.当delta < 0, sqrt (delta) 输出为nan, 但是好像也能计算?
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <queue> #include <map> #include <cmath> typedef long long ll; const int N = 1e5 + 5; const int INF = 0x3f3f3f3f; int main(void) { int T; std::cin >> T; while (T--) { ll a, b, c; std::cin >> a >> b >> c; ll d = b * b - 4 * 1ll * a * c; if (d < 0) puts ("NO"); else { ll e = sqrt (d); if (e * e == d) puts ("YES"); else puts ("NO"); } } return 0; } /* long long long double sqrt () HDU %I64d */
01DP 1002 Jam's balance
原来是背包,暴力枚举是不可做的.dp[i][j] 表示前i个砝码,能称多少的重量,当然砝码也能放在另一边也就是j - w,如果j - w < 0, -(j - w)表示将物品放在堆满砝码的一边,w放在另一边.
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string> #include <queue> #include <map> #include <iostream> #include <cmath> int dp[22][2002]; int main(void) { int T; scanf ("%d", &T); while (T--) { int n; scanf ("%d", &n); memset (dp, 0, sizeof (dp)); dp[0][0] = 1; for (int w, i=1; i<=n; ++i) { scanf ("%d", &w); for (int j=0; j<=2000; ++j) { if (!dp[i-1][j]) continue; dp[i][j] = dp[i][j+w] = 1; dp[i][abs (j-w)] = 1; } } int m; scanf ("%d", &m); for (int w, i=1; i<=m; ++i) { scanf ("%d", &w); if (dp[n][w]) puts ("YES"); else puts ("NO"); } } return 0; } //01dp "twice"
dp(优化) 1003 Jam's maze
这种问方案数的以后应该要想到可能是DP.f[x1][y1][x1][y1]=f[x1][y1-1][x2][y2+1]+f[x1][y1-1][x2+1][y2]+f[x1-1][y1][x2][y2+1]+f[x1-1][y1][x2+1][y2].对它优化,f[i][x1][x2],通过走的步数以及x能计算出当前走到的y,再优化点把第一维改成滚动的,即dp[now][x1][x2] <- dp[now^1][x1][x2] ... dp[now^1][x1][x2]是(x1, y1 - 1) 和 (x2, y2 - 1), 其他类似
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string> #include <queue> #include <map> #include <cmath> typedef long long ll; const int N = 5e2 + 5; const int MOD = 5201314; int dp[2][N][N]; char str[N][N]; void add(int &a, int b) { a += b; if (a >= MOD) a %= MOD; } int main(void) { int T; scanf ("%d", &T); while (T--) { int n; scanf ("%d", &n); for (int i=1; i<=n; ++i) scanf ("%s", str[i] + 1); if (str[1][1] != str[n][n]) puts ("0"); else { memset (dp, 0, sizeof (dp)); int now = 0; dp[now][1][n] = 1; for (int s=1; s<n; ++s) { now ^= 1; memset (dp[now], 0, sizeof (dp[now])); for (int x1=1; x1<=n; ++x1) { for (int x2=n; x2>=1; --x2) { if (x1 - 1 > s || n - x2 > s) continue; int y1 = 1 + s - (x1 - 1); int y2 = n - (s - (n - x2)); if (str[x1][y1] != str[x2][y2]) continue; add (dp[now][x1][x2], dp[now^1][x1][x2]); add (dp[now][x1][x2], dp[now^1][x1][x2+1]); add (dp[now][x1][x2], dp[now^1][x1-1][x2]); add (dp[now][x1][x2], dp[now^1][x1-1][x2+1]); } } } int ans = 0; for (int i=1; i<=n; ++i) add (ans, dp[now][i][i]); printf ("%d ", ans); } } return 0; }