DP练习(概率,树状,状压)
http://vjudge.net/contest/view.action?cid=51211#overview
花了好长时间了,终于把这个专题做了绝大部分了
A:HDU 3853
最简单的概率DP求期望,从终点推到起点就是了,注意一个坑就是如果p1=1那么他一旦到达这个点,那么就永远走不出去了
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e9 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 26 //typedef __int64 LL; 27 //typedef long long LL; 28 const int MAXN = 1005; 29 const int MAXM = 100005; 30 const double eps = 1e-13; 31 //const LL MOD = 1000000007; 32 33 double p1[MAXN][MAXN], p2[MAXN][MAXN], p3[MAXN][MAXN], dp[MAXN][MAXN]; 34 35 int main() 36 { 37 int R, C; 38 while(~scanf("%d %d", &R, &C)) 39 { 40 for(int i=1;i<=R;i++) 41 for(int j=1;j<=C;j++) 42 scanf("%lf%lf%lf", &p1[i][j], &p2[i][j], &p3[i][j]); 43 mem0(dp); 44 for(int i=R;i>=1;i--) 45 for(int j=C;j>=1;j--) 46 { 47 if(i==R && j==C) continue; 48 if(fabs(p1[i][j] - 1) < eps) continue; 49 dp[i][j] = (dp[i][j+1]*p2[i][j] + dp[i+1][j]*p3[i][j] + 2) / (1-p1[i][j]) ; 50 } 51 printf("%.3lf\n", dp[1][1]); 52 } 53 return 0; 54 }
B:HDU 3920
状态压缩DP 题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e9 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 105; 35 const int MAXM = 100005; 36 const double eps = 1e-13; 37 //const LL MOD = 1000000007; 38 39 int T, N; 40 typedef double Point[2]; 41 Point st, p[MAXN]; 42 double dis[MAXN][MAXN], d[MAXN], dp[1<<21]; 43 44 double calc(Point a, Point b) 45 { 46 double x = a[0] - b[0]; 47 double y = a[1] - b[1]; 48 return sqrt(x*x + y*y); 49 } 50 51 void getDis() 52 { 53 for(int i=0;i<N;i++) 54 { 55 d[i] = calc(st, p[i]); 56 for(int j=i+1;j<N;j++) 57 { 58 dis[j][i] = dis[i][j] = calc(p[i], p[j]); 59 } 60 } 61 } 62 63 int main() 64 { 65 int t = 0; 66 scanf("%d", &T); 67 while(T--) 68 { 69 scanf("%lf %lf", &st[0], &st[1]); 70 scanf("%d", &N); 71 N <<= 1; 72 for(int i=0;i<N;i++) 73 scanf("%lf %lf", &p[i][0], &p[i][1]); 74 getDis(); 75 dp[0] = 0; 76 for(int i=1;i<(1<<N);i++) dp[i] = INF; 77 queue<int>q; 78 q.push(0); 79 while(!q.empty()) 80 { 81 int now = q.front(); q.pop(); 82 int f=0, r; 83 while( now & (1<<f) && f < N) 84 f++; 85 for(r = f + 1; r < N; r ++ ) 86 if(!(now & (1<<r))) 87 { 88 int next = now | (1<<f) | (1<<r); 89 double minDis = MIN(d[f], d[r]) + dis[f][r]; 90 if( fabs(dp[next] - INF) < eps ) 91 { 92 q.push(next); 93 dp[next] = dp[now] + minDis; 94 } 95 else if( dp[now] + minDis < dp[next] ) 96 dp[next] = dp[now] + minDis; 97 } 98 } 99 printf("Case #%d: %.2lf%\n", ++t, dp[(1<<N)-1]); 100 } 101 return 0; 102 }
C:HDU 1520
简单的树形DP 题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e9 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 6010; 35 const int MAXM = 100005; 36 const double eps = 1e-13; 37 //const LL MOD = 1000000007; 38 39 int N, a[MAXN], dp[MAXN][2]; 40 int fa[MAXN]; 41 vector<int>e[MAXN]; 42 43 void DFS(int u) 44 { 45 int s0 = 0, s1 = 0; 46 for(int i=0;i<e[u].size();i++) 47 { 48 DFS(e[u][i]); 49 s0 += MAX( dp[e[u][i]][0], dp[e[u][i]][1] ); 50 s1 += dp[e[u][i]][0]; 51 } 52 dp[u][0] = s0; 53 dp[u][1] = s1 + a[u]; 54 } 55 56 int main() 57 { 58 //FOPENIN("in.txt"); 59 while(~scanf("%d", &N)) 60 { 61 mem0(dp); 62 for(int i=1;i<=N;i++) 63 { 64 scanf("%d", &a[i]); 65 fa[i] = i; 66 e[i].clear(); 67 } 68 int x, y; 69 while(scanf("%d %d", &x, &y) && (x||y) ){ 70 e[y].push_back(x); 71 fa[x] = y; 72 } 73 int ans = 0; 74 for(int i=1;i<=N;i++) if(fa[i] == i) 75 { 76 DFS(i); 77 ans += MAX(dp[i][0], dp[i][1]); 78 } 79 printf("%d\n", ans); 80 } 81 return 0; 82 }
D:HDU 4284
状态压缩DP 题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e8 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 600; 35 const int MAXM = 100005; 36 const double eps = 1e-13; 37 //const LL MOD = 1000000007; 38 39 int T, N, M, H, Money; 40 int dis[MAXN][MAXN], add[MAXN], cost[MAXN]; 41 int citys[20], dp[1<<18][18]; 42 43 void init() 44 { 45 int u, v, w, c, a; 46 mem0(add); mem0(cost);mem1(dp); 47 scanf("%d %d %d", &N, &M, &Money); 48 for(int i =0 ; i <= N ;i ++ ) 49 { 50 dis[i][i] = 0; 51 for(int j = 0; j <= N ; j ++ ) 52 if(i != j) dis[i][j] = INF; 53 } 54 for(int i = 0; i < M; i ++ ) 55 { 56 scanf("%d %d %d", &u, &v, &w); 57 dis[u][v] = dis[v][u] = MIN(dis[u][v], w); 58 } 59 scanf("%d", &H); 60 for(int i = 1; i <= H; i ++ ) 61 { 62 scanf("%d %d %d", &u, &a, &c); 63 citys[i] = u; 64 add[i] = a; 65 cost[i] = c; 66 } 67 } 68 69 void floyd() 70 { 71 for(int k=1;k<=N;k++) 72 for(int i=1;i<=N;i++) 73 for(int j=1;j<=N;j++) 74 { 75 dis[i][j] = MIN(dis[i][j], dis[i][k] + dis[k][j]); 76 } 77 } 78 79 int main() 80 { 81 //FOPENIN("in.txt"); 82 while(~scanf("%d", &T)) while(T--) 83 { 84 init(); 85 floyd(); 86 int ans = -INF; H += 1; 87 citys[0] = 1; cost[0] = add[0] = 0; 88 dp[1][0] = Money; 89 for(int now = 1; now < (1<<H); now ++ ) 90 { 91 for(int u = 0; u < H; u ++ ) if(dp[now][u] != -1) 92 { 93 for(int v = 1; v < H; v ++ ) if( (now & (1<<v)) == 0 ) 94 { 95 int next = now | (1<<v); 96 if(dp[now][u] >= dis[citys[u]][citys[v]] + cost[v] ) 97 { 98 dp[next][v] = MAX(dp[now | (1<<v)][v], dp[now][u] - dis[citys[u]][citys[v]] - cost[v] + add[v]); 99 } 100 if(next == (1<<H) - 1) 101 { 102 ans = MAX(ans, dp[next][v]); 103 } 104 } 105 } 106 } 107 //printf("%d\n", ans); 108 printf("%s\n", ans >= 0 ? "YES" : "NO"); 109 } 110 return 0; 111 }
E:HDU 2196
比较好的题目了,两次DFS,求树上任意点触发的最长距离 题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e8 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 10005; 35 const int MAXM = 20005; 36 const double eps = 1e-13; 37 //const LL MOD = 1000000007; 38 39 int N; 40 int head[MAXN], next[MAXM], tot; 41 int u[MAXM], v[MAXM], w[MAXM]; 42 int fir[MAXN], sec[MAXN], ans[MAXN]; 43 44 void addEdge(int U, int V, int W) 45 { 46 u[tot] = U; 47 v[tot] = V; 48 w[tot] = W; 49 next[tot] = head[U]; 50 head[U] = tot; 51 tot ++; 52 } 53 54 int dfs1(int x, int fa) 55 { 56 fir[x] = sec[x] = 0; 57 for(int e = head[x]; e != -1; e = next[e]) if(v[e] != fa) 58 { 59 int dis = dfs1(v[e], x) + w[e]; 60 if(dis >= fir[x]) { sec[x] = fir[x]; fir[x] = dis; } 61 else if(dis > sec[x]) sec[x] = dis; 62 } 63 return fir[x]; 64 } 65 66 void dfs2(int x, int fa, int dis) 67 { 68 ans[x] = MAX(fir[x], dis); 69 for(int e = head[x]; e != -1; e = next[e]) if(v[e] != fa) 70 { 71 int y = v[e]; 72 if(fir[y] + w[e] == fir[x]) 73 dfs2(y, x, MAX( dis, sec[x]) + w[e] ); 74 else 75 dfs2(y, x, MAX( dis, fir[x]) + w[e] ); 76 } 77 } 78 79 int main() 80 { 81 82 while(~scanf("%d", &N)) 83 { 84 tot = 0; 85 mem1(head); 86 int V, W; 87 for(int i = 2; i <= N; i ++) 88 { 89 scanf("%d %d", &V, &W); 90 addEdge(i, V, W); 91 addEdge(V, i, W); 92 } 93 dfs1(1, 1); 94 dfs2(1, 1, 0); 95 for(int i = 1; i <= N; i ++ ) 96 printf("%d\n", ans[i]); 97 } 98 return 0; 99 }
F:HDU 4539
最原始最薄里的状压DP 题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e8 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 10000; 35 const int MAXM = 100005; 36 const double eps = 1e-13; 37 //const LL MOD = 1000000007; 38 39 int N, M; 40 int ma[110]; 41 int dp[2][200][200]; 42 43 int stNum; 44 int st[1000], num[1000]; 45 46 int judge(int x) 47 { 48 if(x & (x<<2)) return 0; 49 return 1; 50 } 51 52 int get1(int x) 53 { 54 int ret = 0; 55 while(x) 56 { 57 ret += x & 1; 58 x >>= 1; 59 } 60 return ret; 61 } 62 63 void init() 64 { 65 mem1(dp);mem0(ma); 66 stNum = 0; 67 for(int i=0;i<(1<<M);i++) if(judge(i)) 68 { 69 st[stNum] = i; 70 num[stNum++] = get1(i); 71 } 72 } 73 74 75 int main() 76 { 77 //FOPENIN("in.txt"); 78 while(~scanf("%d %d%*c", &N, &M)) 79 { 80 init(); 81 int x, cur = 0; 82 for(int i=1;i<=N;i++) 83 for(int j=0;j<M;j++) { 84 scanf("%d", &x); 85 if(x==0) ma[i] |= (1<<j); 86 } 87 for(int i=0;i<stNum;i++) { 88 if(st[i] & ma[1]) continue; 89 dp[cur][i][0] = num[i]; 90 } 91 for(int r = 2; r <= N; r ++) 92 { 93 cur = !cur; 94 for(int i = 0; i < stNum; i ++) 95 { 96 if(st[i] & ma[r]) continue; 97 for(int j = 0; j < stNum; j ++ ) 98 { 99 if(st[j] & ma[r-1]) continue; 100 int p = (st[i]<<1) | (st[i]>>1); 101 if(st[j] & p) continue; 102 for(int k = 0; k < stNum; k ++) if(dp[!cur][j][k] != -1) 103 { 104 int pp = st[i] | ((st[j]<<1) | (st[j]>>1)); 105 if(st[k] & pp) continue; 106 dp[cur][i][j] = MAX(dp[cur][i][j], dp[!cur][j][k] + num[i]); 107 } 108 109 } 110 } 111 } 112 int ans = 0; 113 for(int i=0;i<stNum;i++) for(int j=0;j<stNum;j++) 114 ans = MAX(ans, dp[cur][i][j]); 115 printf("%d\n", ans); 116 } 117 return 0; 118 } 119 120 121 /* 122 123 6 124 3 125 2 126 12 127 128 */
G:HDU 4035
推公式很重要,是看别人做的。。。。题解
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 1e8 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, mid 19 #define rson k<<1|1, mid+1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FOPENIN(IN) freopen(IN, "r", stdin) 24 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 25 template<class T> T CMP_MIN(T a, T b) { return a < b; } 26 template<class T> T CMP_MAX(T a, T b) { return a > b; } 27 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 28 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 31 32 //typedef __int64 LL; 33 //typedef long long LL; 34 const int MAXN = 10005; 35 const int MAXM = 100005; 36 const double eps = 1e-10; 37 //const LL MOD = 1000000007; 38 39 int T, N; 40 vector<int>v[MAXN]; 41 double k[MAXN], e[MAXN]; 42 double A[MAXN], B[MAXN], C[MAXN]; 43 44 45 void init() 46 { 47 int U, V; 48 scanf("%d", &N); 49 for(int i=0;i<=N;i++) v[i].clear(); 50 for(int i=0;i<N-1;i++) 51 { 52 scanf("%d %d", &U, &V); 53 v[U].push_back(V); 54 v[V].push_back(U); 55 } 56 for(int i=1;i<=N;i++) 57 { 58 scanf("%d %d", &U, &V); 59 k[i] = (double)U / 100.0; 60 e[i] = (double)V / 100.0; 61 } 62 } 63 64 bool DFS(int x, int fa) 65 { 66 A[x] = k[x]; 67 B[x] = (1 - k[x] - e[x]) / v[x].size(); 68 C[x] = 1 - k[x] - e[x]; 69 if(v[x].size() == 1 && x != fa) 70 return true; 71 double temp = 0; 72 for(int i = 0; i < v[x].size() ; i ++ ) 73 { 74 int y = v[x][i]; 75 if(y == fa) continue; 76 if(!DFS(y, x)) return false; 77 A[x] += A[y] * B[x]; 78 C[x] += C[y] * B[x]; 79 temp += B[y] * B[x]; 80 } 81 if(fabs(temp - 1.0) < eps) return false; 82 A[x] = A[x] / (1 - temp); 83 B[x] = B[x] / (1 - temp); 84 C[x] = C[x] / (1 - temp); 85 return true; 86 } 87 88 int main() 89 { 90 //FOPENIN("in.txt"); 91 scanf("%d", &T); 92 for(int t = 1; t <= T; t ++ ) 93 { 94 init(); 95 if( DFS(1, 1) && fabs(A[1] - 1.0) > eps ) 96 { 97 printf("Case %d: %lf\n", t, C[1] / (1 - A[1])); 98 } 99 else 100 { 101 printf("Case %d: impossible\n", t); 102 } 103 } 104 }
I:HDU 1561
树形DP,注意状态转化的过程 题解
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF ((LL)100000000000000000) 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FOPENIN(IN) freopen(IN, "r", stdin) 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 24 template<class T> T CMP_MIN(T a, T b) { return a < b; } 25 template<class T> T CMP_MAX(T a, T b) { return a > b; } 26 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 27 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 30 31 //typedef __int64 LL; 32 typedef long long LL; 33 const int MAXN = 255; 34 const int MAXM = 110000; 35 const double eps = 1e-12; 36 int dx[4] = {-1, 0, 0, 1}; 37 int dy[4] = {0, -1, 1, 0}; 38 39 int N, M; 40 int G[MAXN][MAXN], vis[MAXN], num[MAXN]; 41 int DP[MAXN][MAXN], D[MAXN]; 42 43 void DFS(int u) 44 { 45 vis[u] = 1; 46 DP[u][1] = num[u]; 47 for(int i=1;i<=N;i++) if(G[u][i]) 48 { 49 if(!vis[i]) DFS(i); 50 for(int j=M;j>0;j--)//这里为了保证是先从父节点更新,需要逆序 51 for(int k=0;k<j;k++)//k<j保证父节点不会被更新掉 52 DP[u][j] = MAX(DP[u][j], DP[u][j-k] + DP[i][k]); 53 } 54 } 55 56 int main() 57 { 58 //FOPENIN("in.txt"); 59 while(~scanf("%d %d", &N, &M) &&( N||M)) 60 { 61 int a;mem0(G);mem0(D);mem0(vis);mem0(DP); 62 for(int i=1;i<=N;i++) { 63 scanf("%d %d", &a, &num[i]); 64 if(a != 0)G[a][i] = 1; 65 else D[i] = 1; 66 } 67 for(int i=1;i<=N;i++) if(!vis[i]){ 68 DFS(i); 69 if(D[i]) for(int j=M;j>=0;j--)//同样需要逆序,可以取到0 70 { 71 for(int k=0;k<=j;k++) 72 DP[0][j] = MAX(DP[0][j], DP[0][j-k] + DP[i][k]); 73 } 74 } 75 printf("%d\n", DP[0][M]); 76 77 } 78 return 0; 79 }
J:HDU 4870
1。高斯消元的做法
2。公式推倒很重要
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF ((LL)100000000000000000) 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FOPENIN(IN) freopen(IN, "r", stdin) 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 24 template<class T> T CMP_MIN(T a, T b) { return a < b; } 25 template<class T> T CMP_MAX(T a, T b) { return a > b; } 26 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 27 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 30 31 //typedef __int64 LL; 32 typedef long long LL; 33 const int MAXN = 255; 34 const int MAXM = 110000; 35 const double eps = 1e-12; 36 37 double t[30]; 38 39 int main() 40 { 41 //FOPENIN("in.txt"); 42 double p; 43 while(~scanf("%lf", &p)) 44 { 45 t[0] = 0; 46 t[1] = 1 / p; 47 t[2] = 1 / p + 1 / p / p; 48 for(int i=3;i<=20;i++) 49 { 50 t[i] = 1 / p * t[i-1] + 1 / p - (1-p) / p * t[i-3]; 51 } 52 double ans = 2 *t[19] + t[20] - t[19]; 53 printf("%lf\n", ans); 54 } 55 return 0; 56 }
K:POJ 1160
我就喜欢暴力求解 题解
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 100000000 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FOPENIN(IN) freopen(IN, "r", stdin) 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 24 template<class T> T CMP_MIN ( T a, T b ) { return a < b; } 25 template<class T> T CMP_MAX ( T a, T b ) { return a > b; } 26 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; } 27 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; } 28 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; } 29 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; } 30 template<class T> T SWAP( T& a, T& b ) { T t = a; a = b; b = t; } 31 32 //typedef __int64 LL; 33 typedef long long LL; 34 const int MAXN = 255; 35 const int MAXM = 110000; 36 const double eps = 1e-12; 37 38 int V, P; 39 int x[310], DP[3][35][310]; 40 int dis[310][310], pre[310]; 41 42 void initDis() 43 { 44 mem0(dis);mem0(pre); 45 for(int i=1;i<=V;i++) 46 for(int j=i;j<=V;j++) 47 for(int k=i;k<=j;k++) 48 dis[i][j] += MIN(x[k]-x[i], x[j]-x[k]); 49 for(int i=1;i<=V;i++)for(int j=i;j>=1;j--) 50 pre[i] += x[i] - x[j]; 51 } 52 53 int main() 54 { 55 //FOPENIN ( "in.txt" ); 56 //FOPENOUT("out.txt"); 57 while(~scanf("%d %d", &V, &P)) 58 { 59 for(int i=1;i<=V;i++) 60 scanf("%d", &x[i]); 61 initDis(); 62 for(int i=0;i<2;i++) 63 for(int j=0;j<=MIN(i,P);j++) 64 for(int k=0;k<=i;k++){ 65 DP[i][j][k] = INF; 66 } 67 int now = 0; 68 for(int i=1;i<=V;i++) 69 { 70 now = !now; 71 int s = 0; 72 for(int j=1;j<=i;j++) DP[now][1][j] = pre[j]; 73 for(int j=2;j<=MIN(i, P); j++) 74 { 75 DP[now][j][i] = INF; 76 for(int k=j-1;k<i;k++)if(DP[!now][j-1][k] != INF) 77 { 78 DP[now][j][i] = MIN(DP[now][j][i], DP[now][j-1][k] + dis[k][i]); 79 } 80 for(int k=j;k<i;k++) DP[now][j][k] = DP[!now][j][k]; 81 } 82 } 83 int ans = INF; 84 for(int k=P;k<=V;k++)if(DP[now][P][k] != INF) 85 { 86 int s = 0; 87 for(int j = k + 1; j <= V; j ++ ) s += x[j] - x[k]; 88 ans = MIN(ans, DP[now][P][k] + s); 89 } 90 printf("%d\n", ans); 91 } 92 return 0; 93 }