DP练习(概率,树状,状压)
http://vjudge.net/contest/view.action?cid=51211#overview
花了好长时间了,终于把这个专题做了绝大部分了
A:HDU 3853
最简单的概率DP求期望,从终点推到起点就是了,注意一个坑就是如果p1=1那么他一旦到达这个点,那么就永远走不出去了
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e9
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- double p1[MAXN][MAXN], p2[MAXN][MAXN], p3[MAXN][MAXN], dp[MAXN][MAXN];
- int main()
- {
- int R, C;
- while(~scanf("%d %d", &R, &C))
- {
- for(int i=;i<=R;i++)
- for(int j=;j<=C;j++)
- scanf("%lf%lf%lf", &p1[i][j], &p2[i][j], &p3[i][j]);
- mem0(dp);
- for(int i=R;i>=;i--)
- for(int j=C;j>=;j--)
- {
- if(i==R && j==C) continue;
- if(fabs(p1[i][j] - ) < eps) continue;
- dp[i][j] = (dp[i][j+]*p2[i][j] + dp[i+][j]*p3[i][j] + ) / (-p1[i][j]) ;
- }
- printf("%.3lf\n", dp[][]);
- }
- return ;
- }
B:HDU 3920
状态压缩DP 题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e9
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int T, N;
- typedef double Point[];
- Point st, p[MAXN];
- double dis[MAXN][MAXN], d[MAXN], dp[<<];
- double calc(Point a, Point b)
- {
- double x = a[] - b[];
- double y = a[] - b[];
- return sqrt(x*x + y*y);
- }
- void getDis()
- {
- for(int i=;i<N;i++)
- {
- d[i] = calc(st, p[i]);
- for(int j=i+;j<N;j++)
- {
- dis[j][i] = dis[i][j] = calc(p[i], p[j]);
- }
- }
- }
- int main()
- {
- int t = ;
- scanf("%d", &T);
- while(T--)
- {
- scanf("%lf %lf", &st[], &st[]);
- scanf("%d", &N);
- N <<= ;
- for(int i=;i<N;i++)
- scanf("%lf %lf", &p[i][], &p[i][]);
- getDis();
- dp[] = ;
- for(int i=;i<(<<N);i++) dp[i] = INF;
- queue<int>q;
- q.push();
- while(!q.empty())
- {
- int now = q.front(); q.pop();
- int f=, r;
- while( now & (<<f) && f < N)
- f++;
- for(r = f + ; r < N; r ++ )
- if(!(now & (<<r)))
- {
- int next = now | (<<f) | (<<r);
- double minDis = MIN(d[f], d[r]) + dis[f][r];
- if( fabs(dp[next] - INF) < eps )
- {
- q.push(next);
- dp[next] = dp[now] + minDis;
- }
- else if( dp[now] + minDis < dp[next] )
- dp[next] = dp[now] + minDis;
- }
- }
- printf("Case #%d: %.2lf%\n", ++t, dp[(<<N)-]);
- }
- return ;
- }
C:HDU 1520
简单的树形DP 题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e9
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int N, a[MAXN], dp[MAXN][];
- int fa[MAXN];
- vector<int>e[MAXN];
- void DFS(int u)
- {
- int s0 = , s1 = ;
- for(int i=;i<e[u].size();i++)
- {
- DFS(e[u][i]);
- s0 += MAX( dp[e[u][i]][], dp[e[u][i]][] );
- s1 += dp[e[u][i]][];
- }
- dp[u][] = s0;
- dp[u][] = s1 + a[u];
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d", &N))
- {
- mem0(dp);
- for(int i=;i<=N;i++)
- {
- scanf("%d", &a[i]);
- fa[i] = i;
- e[i].clear();
- }
- int x, y;
- while(scanf("%d %d", &x, &y) && (x||y) ){
- e[y].push_back(x);
- fa[x] = y;
- }
- int ans = ;
- for(int i=;i<=N;i++) if(fa[i] == i)
- {
- DFS(i);
- ans += MAX(dp[i][], dp[i][]);
- }
- printf("%d\n", ans);
- }
- return ;
- }
D:HDU 4284
状态压缩DP 题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e8
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int T, N, M, H, Money;
- int dis[MAXN][MAXN], add[MAXN], cost[MAXN];
- int citys[], dp[<<][];
- void init()
- {
- int u, v, w, c, a;
- mem0(add); mem0(cost);mem1(dp);
- scanf("%d %d %d", &N, &M, &Money);
- for(int i = ; i <= N ;i ++ )
- {
- dis[i][i] = ;
- for(int j = ; j <= N ; j ++ )
- if(i != j) dis[i][j] = INF;
- }
- for(int i = ; i < M; i ++ )
- {
- scanf("%d %d %d", &u, &v, &w);
- dis[u][v] = dis[v][u] = MIN(dis[u][v], w);
- }
- scanf("%d", &H);
- for(int i = ; i <= H; i ++ )
- {
- scanf("%d %d %d", &u, &a, &c);
- citys[i] = u;
- add[i] = a;
- cost[i] = c;
- }
- }
- void floyd()
- {
- for(int k=;k<=N;k++)
- for(int i=;i<=N;i++)
- for(int j=;j<=N;j++)
- {
- dis[i][j] = MIN(dis[i][j], dis[i][k] + dis[k][j]);
- }
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d", &T)) while(T--)
- {
- init();
- floyd();
- int ans = -INF; H += ;
- citys[] = ; cost[] = add[] = ;
- dp[][] = Money;
- for(int now = ; now < (<<H); now ++ )
- {
- for(int u = ; u < H; u ++ ) if(dp[now][u] != -)
- {
- for(int v = ; v < H; v ++ ) if( (now & (<<v)) == )
- {
- int next = now | (<<v);
- if(dp[now][u] >= dis[citys[u]][citys[v]] + cost[v] )
- {
- dp[next][v] = MAX(dp[now | (<<v)][v], dp[now][u] - dis[citys[u]][citys[v]] - cost[v] + add[v]);
- }
- if(next == (<<H) - )
- {
- ans = MAX(ans, dp[next][v]);
- }
- }
- }
- }
- //printf("%d\n", ans);
- printf("%s\n", ans >= ? "YES" : "NO");
- }
- return ;
- }
E:HDU 2196
比较好的题目了,两次DFS,求树上任意点触发的最长距离 题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e8
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int N;
- int head[MAXN], next[MAXM], tot;
- int u[MAXM], v[MAXM], w[MAXM];
- int fir[MAXN], sec[MAXN], ans[MAXN];
- void addEdge(int U, int V, int W)
- {
- u[tot] = U;
- v[tot] = V;
- w[tot] = W;
- next[tot] = head[U];
- head[U] = tot;
- tot ++;
- }
- int dfs1(int x, int fa)
- {
- fir[x] = sec[x] = ;
- for(int e = head[x]; e != -; e = next[e]) if(v[e] != fa)
- {
- int dis = dfs1(v[e], x) + w[e];
- if(dis >= fir[x]) { sec[x] = fir[x]; fir[x] = dis; }
- else if(dis > sec[x]) sec[x] = dis;
- }
- return fir[x];
- }
- void dfs2(int x, int fa, int dis)
- {
- ans[x] = MAX(fir[x], dis);
- for(int e = head[x]; e != -; e = next[e]) if(v[e] != fa)
- {
- int y = v[e];
- if(fir[y] + w[e] == fir[x])
- dfs2(y, x, MAX( dis, sec[x]) + w[e] );
- else
- dfs2(y, x, MAX( dis, fir[x]) + w[e] );
- }
- }
- int main()
- {
- while(~scanf("%d", &N))
- {
- tot = ;
- mem1(head);
- int V, W;
- for(int i = ; i <= N; i ++)
- {
- scanf("%d %d", &V, &W);
- addEdge(i, V, W);
- addEdge(V, i, W);
- }
- dfs1(, );
- dfs2(, , );
- for(int i = ; i <= N; i ++ )
- printf("%d\n", ans[i]);
- }
- return ;
- }
F:HDU 4539
最原始最薄里的状压DP 题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e8
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int N, M;
- int ma[];
- int dp[][][];
- int stNum;
- int st[], num[];
- int judge(int x)
- {
- if(x & (x<<)) return ;
- return ;
- }
- int get1(int x)
- {
- int ret = ;
- while(x)
- {
- ret += x & ;
- x >>= ;
- }
- return ret;
- }
- void init()
- {
- mem1(dp);mem0(ma);
- stNum = ;
- for(int i=;i<(<<M);i++) if(judge(i))
- {
- st[stNum] = i;
- num[stNum++] = get1(i);
- }
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d %d%*c", &N, &M))
- {
- init();
- int x, cur = ;
- for(int i=;i<=N;i++)
- for(int j=;j<M;j++) {
- scanf("%d", &x);
- if(x==) ma[i] |= (<<j);
- }
- for(int i=;i<stNum;i++) {
- if(st[i] & ma[]) continue;
- dp[cur][i][] = num[i];
- }
- for(int r = ; r <= N; r ++)
- {
- cur = !cur;
- for(int i = ; i < stNum; i ++)
- {
- if(st[i] & ma[r]) continue;
- for(int j = ; j < stNum; j ++ )
- {
- if(st[j] & ma[r-]) continue;
- int p = (st[i]<<) | (st[i]>>);
- if(st[j] & p) continue;
- for(int k = ; k < stNum; k ++) if(dp[!cur][j][k] != -)
- {
- int pp = st[i] | ((st[j]<<) | (st[j]>>));
- if(st[k] & pp) continue;
- dp[cur][i][j] = MAX(dp[cur][i][j], dp[!cur][j][k] + num[i]);
- }
- }
- }
- }
- int ans = ;
- for(int i=;i<stNum;i++) for(int j=;j<stNum;j++)
- ans = MAX(ans, dp[cur][i][j]);
- printf("%d\n", ans);
- }
- return ;
- }
- /*
- 6
- 3
- 2
- 12
- */
G:HDU 4035
推公式很重要,是看别人做的。。。。题解
- //#pragma comment(linker,"/STACK:102400000,102400000")
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 1e8
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- //const LL MOD = 1000000007;
- int T, N;
- vector<int>v[MAXN];
- double k[MAXN], e[MAXN];
- double A[MAXN], B[MAXN], C[MAXN];
- void init()
- {
- int U, V;
- scanf("%d", &N);
- for(int i=;i<=N;i++) v[i].clear();
- for(int i=;i<N-;i++)
- {
- scanf("%d %d", &U, &V);
- v[U].push_back(V);
- v[V].push_back(U);
- }
- for(int i=;i<=N;i++)
- {
- scanf("%d %d", &U, &V);
- k[i] = (double)U / 100.0;
- e[i] = (double)V / 100.0;
- }
- }
- bool DFS(int x, int fa)
- {
- A[x] = k[x];
- B[x] = ( - k[x] - e[x]) / v[x].size();
- C[x] = - k[x] - e[x];
- if(v[x].size() == && x != fa)
- return true;
- double temp = ;
- for(int i = ; i < v[x].size() ; i ++ )
- {
- int y = v[x][i];
- if(y == fa) continue;
- if(!DFS(y, x)) return false;
- A[x] += A[y] * B[x];
- C[x] += C[y] * B[x];
- temp += B[y] * B[x];
- }
- if(fabs(temp - 1.0) < eps) return false;
- A[x] = A[x] / ( - temp);
- B[x] = B[x] / ( - temp);
- C[x] = C[x] / ( - temp);
- return true;
- }
- int main()
- {
- //FOPENIN("in.txt");
- scanf("%d", &T);
- for(int t = ; t <= T; t ++ )
- {
- init();
- if( DFS(, ) && fabs(A[] - 1.0) > eps )
- {
- printf("Case %d: %lf\n", t, C[] / ( - A[]));
- }
- else
- {
- printf("Case %d: impossible\n", t);
- }
- }
- }
I:HDU 1561
树形DP,注意状态转化的过程 题解
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF ((LL)100000000000000000)
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- int dx[] = {-, , , };
- int dy[] = {, -, , };
- int N, M;
- int G[MAXN][MAXN], vis[MAXN], num[MAXN];
- int DP[MAXN][MAXN], D[MAXN];
- void DFS(int u)
- {
- vis[u] = ;
- DP[u][] = num[u];
- for(int i=;i<=N;i++) if(G[u][i])
- {
- if(!vis[i]) DFS(i);
- for(int j=M;j>;j--)//这里为了保证是先从父节点更新,需要逆序
- for(int k=;k<j;k++)//k<j保证父节点不会被更新掉
- DP[u][j] = MAX(DP[u][j], DP[u][j-k] + DP[i][k]);
- }
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d %d", &N, &M) &&( N||M))
- {
- int a;mem0(G);mem0(D);mem0(vis);mem0(DP);
- for(int i=;i<=N;i++) {
- scanf("%d %d", &a, &num[i]);
- if(a != )G[a][i] = ;
- else D[i] = ;
- }
- for(int i=;i<=N;i++) if(!vis[i]){
- DFS(i);
- if(D[i]) for(int j=M;j>=;j--)//同样需要逆序,可以取到0
- {
- for(int k=;k<=j;k++)
- DP[][j] = MAX(DP[][j], DP[][j-k] + DP[i][k]);
- }
- }
- printf("%d\n", DP[][M]);
- }
- return ;
- }
J:HDU 4870
1。高斯消元的做法
2。公式推倒很重要
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF ((LL)100000000000000000)
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN(T a, T b) { return a < b; }
- template<class T> T CMP_MAX(T a, T b) { return a > b; }
- template<class T> T MAX(T a, T b) { return a > b ? a : b; }
- template<class T> T MIN(T a, T b) { return a < b ? a : b; }
- template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
- template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
- //typedef __int64 LL;
- typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- double t[];
- int main()
- {
- //FOPENIN("in.txt");
- double p;
- while(~scanf("%lf", &p))
- {
- t[] = ;
- t[] = / p;
- t[] = / p + / p / p;
- for(int i=;i<=;i++)
- {
- t[i] = / p * t[i-] + / p - (-p) / p * t[i-];
- }
- double ans = *t[] + t[] - t[];
- printf("%lf\n", ans);
- }
- return ;
- }
K:POJ 1160
我就喜欢暴力求解 题解
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 100000000
- #define inf (-((LL)1<<40))
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
- template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
- template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
- template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
- template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
- template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
- template<class T> T SWAP( T& a, T& b ) { T t = a; a = b; b = t; }
- //typedef __int64 LL;
- typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- int V, P;
- int x[], DP[][][];
- int dis[][], pre[];
- void initDis()
- {
- mem0(dis);mem0(pre);
- for(int i=;i<=V;i++)
- for(int j=i;j<=V;j++)
- for(int k=i;k<=j;k++)
- dis[i][j] += MIN(x[k]-x[i], x[j]-x[k]);
- for(int i=;i<=V;i++)for(int j=i;j>=;j--)
- pre[i] += x[i] - x[j];
- }
- int main()
- {
- //FOPENIN ( "in.txt" );
- //FOPENOUT("out.txt");
- while(~scanf("%d %d", &V, &P))
- {
- for(int i=;i<=V;i++)
- scanf("%d", &x[i]);
- initDis();
- for(int i=;i<;i++)
- for(int j=;j<=MIN(i,P);j++)
- for(int k=;k<=i;k++){
- DP[i][j][k] = INF;
- }
- int now = ;
- for(int i=;i<=V;i++)
- {
- now = !now;
- int s = ;
- for(int j=;j<=i;j++) DP[now][][j] = pre[j];
- for(int j=;j<=MIN(i, P); j++)
- {
- DP[now][j][i] = INF;
- for(int k=j-;k<i;k++)if(DP[!now][j-][k] != INF)
- {
- DP[now][j][i] = MIN(DP[now][j][i], DP[now][j-][k] + dis[k][i]);
- }
- for(int k=j;k<i;k++) DP[now][j][k] = DP[!now][j][k];
- }
- }
- int ans = INF;
- for(int k=P;k<=V;k++)if(DP[now][P][k] != INF)
- {
- int s = ;
- for(int j = k + ; j <= V; j ++ ) s += x[j] - x[k];
- ans = MIN(ans, DP[now][P][k] + s);
- }
- printf("%d\n", ans);
- }
- return ;
- }
DP练习(概率,树状,状压)的更多相关文章
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
- 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)
[题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...
- 【bzoj3672】[Noi2014]购票 斜率优化dp+CDQ分治+树的点分治
题目描述 给出一棵以1为根的带边权有根树,对于每个根节点以外的点$v$,如果它与其某个祖先$a$的距离$d$不超过$l_v$,则可以花费$p_vd+q_v$的代价从$v$到$a$.问从每个点到1花费 ...
- CodeForces 602E【概率DP】【树状数组优化】
题意:有n个人进行m次比赛,每次比赛有一个排名,最后的排名是把所有排名都加起来然后找到比自己的分数绝对小的人数加一就是最终排名. 给了其中一个人的所有比赛的名次.求这个人最终排名的期望. 思路: 渣渣 ...
- luogu4294 [WC2008]游览计划(状压DP/斯坦纳树)
link 题目大意:给定一个网格图,有些点是关键点,选择格点有代价,求把所有关键点联通的最小代价 斯坦纳树模板题 斯坦纳树问题:给定一个图结构,有一些点是关键点,求把这些关键点联通的最小代价e 斯坦纳 ...
- [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp
管道连接 bzoj-4006 JLOI-2015 题目大意:给定一张$n$个节点$m$条边的带边权无向图.并且给定$p$个重要节点,每个重要节点都有一个颜色.求一个边权和最小的边集使得颜色相同的重要节 ...
- 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)
上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...
- 【ZJOI2017 Round1练习&BZOJ4774】D3T2 road(斯坦纳树,状压DP)
题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n − i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d< ...
- [BZOJ4006][JLOI2015]管道连接 状压dp+斯坦纳树
4006: [JLOI2015]管道连接 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1020 Solved: 552[Submit][Statu ...
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
随机推荐
- selinux --chcon命令
chcon命令:修改对象(文件)的安全上下文.比如:用户:角色:类型:安全级别. 命令格式: Chcon [OPTIONS…] CONTEXT FILES….. Chcon [OPTIONS…] –r ...
- opengl截图
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = ; // number of image encoders U ...
- 【C#学习笔记】数组使用
using System; namespace ConsoleApplication { class Program { static void Main(string[] args) { //int ...
- 【网络】js调试F12控制台学习
http://www.cnblogs.com/52cik/p/js-console-acquaintance.html console.log 输出信息 http://javascript.ruany ...
- Android 自定义view中的属性,命名空间,以及tools标签
昨日看到有人在知乎上问这3个琐碎的小知识点,今天索性就整理了一下,其实这些知识点并不难,但是很多开发者平时很少注意到这些, 导致的后果就是开发的时候 经常会被ide报错,开发效率很低,或者看开源代码的 ...
- sort方法的使用、随机数的产生
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序. var arr = ['a','b','m','c','d']; arr.sort(); ...
- python tile函数用法
tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题 ...
- smarty缓存函数
原来在Smarty中在3.0以上版本中不在使用这个clear_all_cache(),而是以$smarty->clearAllCache(); 代替.其中$smarty->clear_ca ...
- 嵌入式 H264中的SPS、PPS提取与作用
使用RTP传输H264的时候,需要用到sdp协议描述,其中有两项:Sequence Parameter Sets (SPS) 和Picture Parameter Set (PPS)需要用到,那么这两 ...
- ajax url参数中文乱码解决
1.较好的处理办法,对js的url中的中文参数值使用两次encodeURI(),即 encodeURI(encodeURI("url的中文参数值")), java代码中使用URLD ...