bupt summer training for 16 #7 ——搜索与DP
https://vjudge.net/contest/174962#overview
A.我们发现重点在于x,y只要累加就ok了
在每个x上只有上下两种状态,所以可以记忆化搜索
f[0/1][i]表示 x = i 时向下/上走,那需要移动多少才能走出去
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn = 500010; 7 8 typedef long long ll; 9 10 ll a[maxn], f[2][maxn]; 11 12 int n, b[2][maxn], vis[2][maxn]; 13 14 ll dfs(int i, int k, ll d = 0) { 15 if(vis[k][i]) { 16 b[k][i] = -1; 17 return f[k][i] = 0; 18 } 19 vis[k][i] = 1; 20 if(!f[k][i]) { 21 int y = i + (k ? a[i] : -a[i]); 22 if(y > n || y <= 1) d = 0; 23 else d = dfs(y, k ^ 1); 24 f[k][i] = d + a[i]; 25 if(y >= 1 && y <= n && b[k ^ 1][y]) b[k][i] = -1; 26 } 27 vis[k][i] = 0; 28 return f[k][i]; 29 } 30 31 int main() { 32 scanf("%d", &n); 33 for(int i = 2;i <= n;i ++) 34 scanf("%I64d", &a[i]); 35 b[0][1] = b[1][1] = -1; 36 for(int i = 2;i <= n;i ++) 37 dfs(i, 0), dfs(i, 1); 38 for(int i = 1;i < n;i ++) { 39 if(b[0][1 + i]) puts("-1"); 40 else printf("%I64d\n", i + f[0][1 + i]); 41 } 42 return 0; 43 }
写狗了又RE又T又WA的...写的丑陋,我。无法忍受
B.非常无脑的爆搜,效率玄学
数据范围个位数还是可以大胆以下的
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int xx[] = {-1, 1, 0, 0}; 7 const int yy[] = {0, 0, 1, -1}; 8 9 int n, m, k; 10 11 char s[10][10]; 12 13 bool vis[10][10]; 14 15 bool dfs(const int &x, const int &y, const int &cc) { 16 if(cc == k) return 1; 17 int nx, ny; 18 for(int i = 0;i < 4;i ++) { 19 nx = x + xx[i], ny = y + yy[i]; 20 if(nx > 0 && nx <= n && ny > 0 && ny <= m && s[nx][ny] != 'S' && !vis[nx][ny]) { 21 vis[nx][ny] = 1; 22 if(dfs(nx, ny, cc + 1)) return 1; 23 vis[nx][ny] = 0; 24 } 25 } 26 return 0; 27 } 28 29 int main() { 30 while(scanf("%d %d", &n, &m), n!= 0) { 31 k = 0; 32 for(int i = 1;i <= n;i ++) { 33 scanf("%s", s[i] + 1); 34 for(int j = 1;j <= m;j ++) 35 vis[i][j] = 0, k += (s[i][j] != 'S'); 36 } 37 vis[1][1] = 1; 38 puts(dfs(1, 1, 1) ? "YES" : "NO"); 39 } 40 return 0; 41 }
C.显而易见的树型DP,依旧写的很糟...
f[i][j]表示从节点 i 向下走距离 j 能获得的最大价值
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 int n, m, s, a[110], f[110][110], g[110][110]; 9 10 vector <pair<int,int> > e[110]; 11 12 void dfs(int u, int fa) { 13 int v, w, i; 14 for(i = 0;i <= m;i ++) g[u][i] = 0; 15 for(i = 0;i < e[u].size();i ++) { 16 v = e[u][i].first; 17 if(v == fa) continue; 18 w = e[u][i].second; 19 dfs(v, u); 20 for(int j = m;j >= 0;j --) 21 for(int k = j;k >= 0;k --) 22 if(j - k - w >= 0) 23 f[u][j] = max(f[u][j], g[u][k] + f[v][j - k - w]); 24 for(int j = 0;j <= m;j ++) 25 g[u][j] = f[u][j]; 26 } 27 for(i = 0;i <= m;i ++) f[u][i] += a[u]; 28 } 29 30 int main() { 31 while(~scanf("%d", &n)) { 32 memset(f, 0, sizeof f); 33 memset(g, 0, sizeof g); 34 memset(e, 0, sizeof e); 35 for(int i = 1;i <= n;i ++) 36 scanf("%d", &a[i]); 37 for(int u, v, w, i = 1;i < n;i ++) { 38 scanf("%d %d %d", &u, &v, &w); 39 e[u].push_back(make_pair(v, w)); 40 e[v].push_back(make_pair(u, w)); 41 } 42 scanf("%d %d", &s, &m), m /= 2; 43 dfs(s, s); 44 printf("%d\n", f[s][m]); 45 } 46 return 0; 47 }
D.大家都会写大龙虾算法让我有些惶恐...
于是决定抄一发队友的dlx板子