Dear 时继
来源:互联网 发布:带网络连接的安全模式 编辑:程序博客网 时间:2024/04/29 00:21
NOIP模板整理
“愿我们的爱恨万古长存。”
基础部分
高精度
模拟版
//好丑QAQ
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 20005;int ca[MAXN],cb[MAXN],cc[MAXN];char a[MAXN],b[MAXN]; int lena,lenb; void jia(){ memset(ca,0,sizeof(ca)); memset(cb,0,sizeof(cb)); memset(cc,0,sizeof(cc)); for(int i = 0 ; i < lena; i ++) ca[i] = a[lena - i - 1] - '0'; for(int i = 0 ; i < lenb; i ++) cb[i] = b[lenb - i - 1] - '0'; int len = 0; while(len <= lena + 2 || len <= lenb + 2) { cc[len] += ca[len] + cb[len]; cc[len + 1] += cc[len] / 10; cc[len] %= 10; len ++; } len += 3; while(true) { if(cc[len] == 0) len --; else break; } if(len == 0) { puts("0"); return; } for(int i = len; i >= 0; i --) printf("%d",cc[i]); return;}void jian(){ memset(ca,0,sizeof(ca)); memset(cb,0,sizeof(cb)); memset(cc,0,sizeof(cc)); for(int i = 0 ; i < lena; i ++) ca[i] = a[lena - i - 1] - '0'; for(int i = 0 ; i < lenb; i ++) cb[i] = b[lenb - i - 1] - '0'; if(lena < lenb) { for(int i = 0; i < lenb; i ++) { cc[i] = ca[i]; ca[i] = cb[i]; cb[i] = cc[i]; } cout << '-'; memset(cc,0,sizeof(cc)); } else if(lena == lenb) { for(int i = lena - 1; i >= 0; i --) { if(ca[i] > cb[i]) break; else if(ca[i] == cb[i]) continue; else { for(int j = i; j >= 0; j --) { cc[j] = ca[j]; ca[j] = cb[j]; cb[j] = cc[j]; } cout << '-'; memset(cc,0,sizeof(cc)); break; } } } memset(cc,0,sizeof(cc)); int len = 0; while(len <= lena + 2 || len <= lenb + 2) { if(ca[len] < cb[len]) { ca[len] += 10; ca[len + 1] --; } cc[len] += ca[len] - cb[len]; len ++; } len += 3; while(true) { if(cc[len] == 0) len --; else break; } if(len == 0) { puts("0"); return; } for(int i = len; i >= 0; i --) printf("%d",cc[i]); return;}void cheng(){ memset(ca,0,sizeof(ca)); memset(cb,0,sizeof(cb)); memset(cc,0,sizeof(cc)); for(int i = 0 ; i < lena; i ++) ca[i] = a[lena - i - 1] - '0'; for(int i = 0 ; i < lenb; i ++) cb[i] = b[lenb - i - 1] - '0'; for(int i = 0; i <= lena + 3; i ++) for(int j = 0; j <= lenb + 3; j ++) cc[i + j] += ca[i] * cb[j]; for(int i = 0; i <= lena + lenb + 4; i ++) if(cc[i] > 9) cc[i + 1] += cc[i] / 10,cc[i] %= 10; int len = lena + lenb + 3; while(true) { if(cc[len] == 0) len --; else break; } if(len == 0) { puts("0"); return; } for(int i = len; i >= 0; i --) printf("%d",cc[i]); return;}/*void gc(int b)//高精除 { bool shit=0; for(int i=len;i>=2;i--) { ans[i-1]+=(ans[i]%b)*10; ans[i]/=b; if(!shit) { if(!ans[i])len--; else shit=1; } } ans[1]/=b; ans[0]=len;}void ggc(int b)//高精除 { bool shit=0; for(int i=tt[0];i>=2;i--) { tt[i-1]+=(tt[i]%b)*10; tt[i]/=b; if(!shit) { if(!tt[i])tt[0]--; else shit=1; } } tt[1]/=b;}*/int main(){ cin >> a >> b; lena = strlen(a); lenb = strlen(b); jia(); jian(); cheng(); return 0;}
子集枚举
//这个并没有用二进制处理
void ds(){ for(int i = 1; i <= n; i ++) if(viv[i] == true) printf("%d ",num[i]); puts(""); return;}void dfs(int now){ if(now > n) { ds(); return; } for(int i = 0; i <= 1; i ++) { viv[now] = i; dfs(now + 1); viv[now] = false; } return;}
归并&&逆序对
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 200005;int n,num[MAXN],xc[MAXN];long long ans = 0;void work(int l,int r){ if(l == r) return; int mid = (l + r) >> 1; work(l,mid);work(mid + 1,r); int ll = l,rl = mid + 1,now = 1; while(ll <= mid && rl <= n) { if(num[ll] > num[rl]) { xc[now] = num[rl]; now ++;rl ++; ans += mid - ll + 1; } else { xc[now] = num[ll]; now ++,ll ++; } } while(ll <= mid) { xc[now] = num[ll]; ll ++;now ++; } while(rl <= n) { xc[now] = num[rl]; rl ++;now ++; } int ssr = r - l + 1; for(int i = 1; i <= ssr; i ++) num[l - 1 + i] = xc[i];//!!! return;}int main(){ memset(num,0,sizeof(num)); memset(xc,0,sizeof(xc)); scanf("%d",&n); for(int i = 1; i <= n; i ++) scanf("%d",&num[i]); work(1,n); printf("%lld\n",ans); return 0;}
全排列
//x表示是否还有空位,当且仅当x>0时,继续放void qpl(int x){ if(x > 0) { for(int i = 1; i <= n; i++) if(b[i]==0)//如果这一位上没有放数 { ans[x]=i;//放上数 b[i]=1;//记录一下放上了数 qpl(x-1);//继续放数 b[i]=0;//放完数了,清空状态 } } else for(int i = n; i >=1; i--) printf("%d ",ans[i]);//放好了数,输出,即为一种排列 printf("\n");}
尺取法
int cqf(){ int l = 0,r = 0; int ans = 0,len = MAXN; while(true) { while(r <= n && ans < S) r ++,ans += num[r]; if(ans < S) break; len = min(len,r - l + 1); ans -= num[l ++]; } return len < n ? len : 0;}
堆排
const int MAXN = 1000005;int n,s,heap[MAXN],cnt = 0;//小根堆 stl默认大根堆 void pop(){ heap[1] = heap[cnt]; int p = 1; while(p * 2 + 1 <= cnt) { int l = p * 2,r = p * 2 + 1; if(heap[l] < heap[p]) { if(heap[r] < heap[l] && heap[r] < heap[p]) swap(l,r);//!!!! swap(heap[l],heap[p]); p = l; } else if(heap[r] < heap[p]) { swap(heap[r],heap[p]); p = r; } else break; } cnt --;}void push(int x){ cnt ++; int p = cnt; heap[p] = x; //顺序…… // int l = p * 2,r = p * 2 + 1; while(p != 1) { int f = p / 2;//!!!!!! if(heap[f] > heap[p]) { swap(heap[f],heap[p]); p = f; } else break; } return;}int main(){ scanf("%d",&n); for(int i = 1; i <= n; i ++) { scanf("%d",&s); push(s); } for(int i = 1; i <= n; i ++) { printf("%d ",heap[1]); pop(); } return 0;}
手动读入
inline int read(){ char ch = getchar(); int f = 1, x = 0; while(!(ch >= '0' && ch <= '9')){if(ch == '-')f = -1;ch = getchar();} while(ch >= '0' && ch <= '9') {x = x * 10 + (ch - '0');ch = getchar();} return x * f;}
⑧数码问题
爱情之路
数据结构
并查集
int find(int x){ return x == fa[x] ? x : fa[x] = find(fa[x]);}bool same(int x,int y){ return find(x) == find(y);}void merge(int x,int y){ x = find(x),y = find(y); if(rank[x] < rank[y]) swap(x,y); fa[x] = y; if(rank[x] == rank[y]) rank[y] ++; return;}
树状数组
int lowbit(int x){ return x&(-x);}void add(int x,int y){ while(x <= n) { tree[x] += y; x += lowbit(x); } return;}int sum(int x){ int s = 0; while(x) { s += tree[x]; x -= lowbit(x); } return s;}int answer(int x,int y){ return sum(y) - sum(x - 1);}int num[MAXN];int main(){ memset(tree,0,sizeof(tree)); scanf("%d",&n); for(int i = 1; i <= n; i ++) { scanf("%d",&num[i]); add(i,num[i] - num[i - 1]); } scanf("%d",&m); for(int j = 1; j <= m; j ++) { scanf("%d",&t); if(t == 1) { scanf("%d %d %d",&a,&b,&y); add(a,y); add(b + 1,-y); } else if(t == 2) { scanf("%d",&y); printf("%d\n",sum(y)); } } return 0;}
线段树
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define L(x) (x << 1)//左儿子#define R(x) (x << 1 | 1)//右儿子#define sz(x) (tree[x].r - tree[x].l + 1)//区间大小using namespace std;const long long MAXN = 200000 + 5;long long num[MAXN];// l == 左;r == 右;p == now;struct dot{ long long l,r; long long add,sum;//修改求和 long long min,max;//最值标记 bool xczhw;//没用打着玩……这是个梗QAQ}tree[MAXN << 2];//标记下放们 p == nowvoid update(long long p){ tree[p].sum = tree[L(p)].sum + tree[R(p)].sum; tree[p].max = max(tree[L(p)].max,tree[R(p)].max); tree[p].min = min(tree[L(p)].min,tree[R(p)].min); return;}void spread(long long p){ if(!tree[p].add) return; tree[L(p)].max += tree[p].add; tree[R(p)].max += tree[p].add; tree[L(p)].min += tree[p].add; tree[R(p)].min += tree[p].add; tree[L(p)].add += tree[p].add; tree[R(p)].add += tree[p].add; tree[L(p)].sum += tree[p].add * sz(L(p)); tree[R(p)].sum += tree[p].add * sz(R(p)); tree[p].add = 0;//!!!!!!! update(p); return;}//简单的建立void build(long long l,long long r,long long p){ tree[p].l = l,tree[p].r = r; if(l == r) { tree[p].min = tree[p].max = tree[p].sum = num[l]; return; } long long mid = (tree[p].l + tree[p].r) >> 1; build(l,mid,L(p)); build(mid+1,r,R(p)); update(p); return;}//区间修改void change(long long l,long long r,long long p,long long v){ if(l <= tree[p].l && tree[p].r <= r) { tree[p].add += v; tree[p].min += v; tree[p].max += v; tree[p].sum += v*sz(p); return; } spread(p); long long mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) change(l,r,L(p),v); if(mid < r) change(l,r,R(p),v); update(p); return;}//区间求和long long ask_sum(long long l,long long r,long long p){ if(l <= tree[p].l && tree[p].r <= r) { return tree[p].sum; } spread(p); long long ans = 0,mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) ans += ask_sum(l,r,L(p)); if(mid < r) ans += ask_sum(l,r,R(p)); update(p); return ans;}//区间最大值long long ask_max(long long l,long long r,long long p){ if(l <= tree[p].l && tree[p].r <= r) { return tree[p].max; } spread(p); long long ans = 0,mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) ans = max(ans,ask_max(l,r,L(p))); if(mid < r) ans = max(ans,ask_max(l,r,R(p))); update(p); return ans;}//区间最小值long long ask_min(long long l,long long r,long long p){ if(l <= tree[p].l && tree[p].r <= r) { return tree[p].min; } spread(p); long long ans = 2333333,mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid) ans = min(ans,ask_min(l,r,L(p))); if(mid < r) ans = min(ans,ask_min(l,r,R(p))); update(p); return ans;}long long n,m,a,b,c;string t;int main(){ memset(num,0,sizeof(num)); scanf("%lld",&n); for(long long i = 1; i <= n; i ++) scanf("%lld",&num[i]); build(1,n,1); scanf("%lld",&m); for(long long i = 1; i <= m; i ++) { cin >> t; if(t == "add") { scanf("%lld %lld %lld",&a,&b,&c); change(a,b,1,c); } else if(t == "sum") { scanf("%lld %lld",&a,&b); printf("%lld\n",ask_sum(a,b,1)); } else if(t == "max") { scanf("%lld %lld",&a,&b); printf("%lld\n",ask_max(a,b,1)); } else if(t == "min") { scanf("%lld %lld",&a,&b); printf("%lld\n",ask_min(a,b,1)); } } return 0;}
图论
货车运输
玛丽卡
1.最短路
floyd
void floyd(){ for(int k = 1; k <= n; k ++) for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);}
spfa_slf
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int MAXN = 200005;int n,m,tot = 0,s,e,f,t,v;int first[MAXN],next[MAXN],dis[MAXN];bool use[MAXN];struct edge{ int f,t,v;}l[MAXN];void build(int f,int t,int v){ l[++ tot] = (edge){f,t,v}; next[tot] = first[f]; first[f] = tot; return;}deque < int > q;void spfa(int s){ while(!q.empty()) q.pop_front(); memset(dis,0x3f,sizeof(dis)); memset(use,0,sizeof(use)); use[s] = true; dis[s] = 0; q.push_back(s); while(!q.empty()) { int u = q.front(); q.pop_front(); use[u] = false; for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; if(dis[w] > dis[u] + l[i].v) { dis[w] = dis[u] + l[i].v; if(!use[w]) { if(q.empty()) q.push_front(w); else if(dis[w] < dis[q.front()]) q.push_front(w); else q.push_back(w); use[w] = true;//…… } } } } return;}int main(){ memset(first,0xff,sizeof(first)); scanf("%d %d %d %d",&n,&m,&s,&e); for(int i = 1; i <= m ; i ++) { scanf("%d %d %d",&f,&t,&v); build(f,t,v);build(t,f,v); } spfa(s); printf("%d\n",dis[e]); return 0;}
dij_heap
struct re{ int u,v; bool operator < (const re &b)const { return v > b.v; }};priority_queue < re > q;int dij(int s,int e){ memset(use,0,sizeof(use)); while(!q.empty()) q.pop(); q.push((re){s,0}); while(!q.empty()) { re us = q.top(); q.pop(); int u = us.u; if(u == e) return us.v; if(use[u]) continue; use[u] = true; for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; int rs = us.v + l[i].v; q.push((re){w,rs}); } } return -1;}
2.最小生成树
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 20005;int n,f,t,v,tot = 0;int fa[MAXN],deep[MAXN];struct edge{ int f,t,v;}l[MAXN];int find(int x){ return x == fa[x] ? x : fa[x] = find(fa[x]);}bool same(int x,int y){ return find(x) == find(y);}bool cmp(edge a,edge b){ return a.v < b.v;}void init(){ memset(deep,0,sizeof(deep)); for(int i = 1; i <= n; i ++) fa[i] = i; return;}void merge(int x,int y){ x = find(x),y = find(y); if(deep[x] > deep[y]) swap(x,y); fa[x] = y; if(deep[x] == deep[y]) deep[y] ++; return;}int kru(){ int ans = 0; sort(l + 1,l + tot + 1,cmp); for(int i = 1; i <= tot; i ++) if(!same(l[i].f,l[i].t)) { ans += l[i].v; merge(l[i].f,l[i].t); } return ans;}int main(){ memset(first,0xff,sizeof(first)); scanf("%d",&n); init(); for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) { scanf("%d",&v); if(i == j) continue; tot ++; l[tot].f = i,l[tot].t = j,l[tot].v = v; } printf("%d\n",kru()); return 0; }
3.次短路
deque<int>q;void spfa_slf(int s){ memset(dis,0x3f,sizeof(dis)); memset(pre,0x3f,sizeof(pre)); memset(use,0,sizeof(use)); q.push_back(0); q.push_back(s); use[s] = true; dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop_front(); use[u] = false; for(int i = first[u];i != -1; i = next[i]) { int w = l[i].t; if(dis[w] > dis[u] + l[i].v) { pre[w] = dis[w]; dis[w] = dis[u] + l[i].v; if(!use[w]) { if(q.empty()) q.push_front(w); else if(dis[w] < dis[q.front()]) q.push_front(w); else q.push_back(w); use[w] = true; } }//如果可以更新最短路,那么就让它更新吧//更新后的最短路是最短路,更新之前的最短路是当前的次短路 else if(pre[w] > dis[u] + l[i].v && dis[w] < dis[u] + l[i].v) { pre[w] = dis[u] + l[i].v; if(!use[w]) { if(q.empty()) q.push_front(w); else if(dis[w] < dis[q.front()]) q.push_front(w); else q.push_back(w); use[w] = true; } }//如果不能更新最短路,但是可以更新次短路,那么就让它更新吧 else if(pre[w] > pre[u] + l[i].v) { pre[w] = pre[u] + l[i].v; if(!use[w]) { if(q.empty()) q.push_front(w); else if(dis[w] < dis[q.front()]) q.push_front(w); else q.push_back(w); use[w] = true; } } //次短路可以更新次短路,那么就让它更新吧 } } return;}
4.K短路
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int MAXN = 200005;int first[MAXN],next[MAXN],tot = 0;int n,m,s,t,K,f,t,v;int h[MAXN],dis[MAXN];bool use[MAXN];struct edge{ int f,t,v;}l[MAXN];struct zt{ int u,v; bool operator < (const int &b) const { return v + h[u] > b.v + h[b.u]; }};void build(int f,int t,int v){ l[++ tot] = (edge){f,t,v}; next[tot] = first[f]; first[f] = tot; return;}priority_queue < zt > q;void dij(int s){ memset(dis,0x3f,sizeof(dis)); dis[s] = 0;q.push((zt){s,0}); while(!q.empty()) { zt x = q.top(); p.pop(); int u = x.u; for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; if(dis[w] > dis[u] + l[i].v) { dis[w] = dis[u] + l[i].v; q.push((zt){w,dis[w]}); } } } return;}int dij_k(int s,int e,int k){ if(s == e) k ++; q.push((zt){s,0}); while(!q.empty()) { zt x = q.top(); int u = x.u; q.pop(); if(u == e) { k --; if(k == 0) return x.v; } for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; int c = x.v + l[i].v; q.push((zt){w,c}); } } return -1;}
5.LCA
void make_tree(int x,int f,int v){ deep[x] = deep[f] + 1; fa[x][0] = f;rank[x] = v; for(int i = first[x]; i != -1; i = next[i]) if(l[i].t != f) make_tree(l[i].t,x,v + l[i].v); return;}void make_lca(){ for(int j = 1; j <= log2(n); j ++) for(int i = 1; i <= n; i ++) fa[i][j] = fa[fa[i][j - 1]][j - 1]; return;}int lca(int x,int y){ if(deep[x] < deep[y]) swap(x,y); for(int i = log2(n); i >= 0; i --) if(deep[fa[x][i]] >= deep[y]) x = fa[x][i]; if(x == y) return x; for(int i = log2(n); i >= 0; i --) if(fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i]; return fa[x][0];}int main(){ memset(first,0xff,sizeof(first)); scanf("%d",&n); for(int i = 1; i < n; i ++) { scanf("%d %d %d",&f,&t,&v); build(f,t,v); build(t,f,v); } make_tree(0,n,0); make_lca(); scanf("%d",&m); for(int i = 1; i <= m; i ++) { scanf("%d %d",&f,&t); printf("%d\n",rank[f] + rank[t] - (rank[lca(f,t)] << 1)); } return 0;}
6.二分图染色
queue < int > q;int work(int s){ while(!q.empty()) q.pop(); int cnt1 = 0,cnt2 = 0; use[s] = true; color[s] = 1; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); if(color[u] == 1) cnt1 ++; else cnt2 ++; for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; if(!use[w]) { color[w] = 1 - color[u]; use[w] = true; q.push(w); } else if(color[w] == color[u]) return -1; } } return ans += min(cnt1,cnt2);}
7.Tarjan
int first[MAXN],next[MAXN];int low[MAXN],dfn[MAXN];int scc_num,dfs_clock,scc[MAXN];stack < int > s;int dfs(int u){ low[u] = dfn[u] = ++ dfs_clock; s.push(u); for(int i = first[u]; i != -1; i = next[i]) { int w = l[i].t; if(!dfn[w]) { dfs(w); low[u] = min(low[w],low[u]); } else if(!scc[w]) low[u] = min(low[u],dfn[w]); } if(low[u] == dfn[u]) { scc_num ++; while(true) { int x = s.top(); s.pop(); scc[x] = scc_num; if(x == u) break; } } return;}
8.dfs找环
void dfs(int x){ int k = x,cnt = 0; while(true) { times[x] = cnt ++; use[x] = k; x = t[x]; if(use[x] > 0) { if(use[x] == k) { ans = min(ans,cnt - times[x]); break; } else { ans = ans; break; } } }}int main(){ memset(t,0,sizeof(t)); memset(use,0,sizeof(use)); scanf("%d",&n); for(int i = 1; i <= n; i ++) scanf("%d",&t[i]); for(int i = 1; i <= n; i ++) if(use[i] == 0) dfs(i); printf("%d\n",ans); return 0;}
9.拓扑排序
void topsort(){ for(int i = 1; i <= n; i ++) if(!rudu[i]) q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); printf("%d ",u); for(int i = first[i]; i != -1; i = next[i]) { int w = l[i].t; rudu[w] --; if(!rudu[w]) q.push(w); } } return;} void init(){ scanf("%d",&n); for(int i = 1; i <= n; i ++) { while(true) { scanf("%d",&x); if(x == 0) break; build(i,x); rudu[x] ++; } } return;}
数论
int gcd(int a, int b){ // a > b if(b == 0) return a; return gcd(b,a % b);}int lcm(int x, int y){ int c; c = x * y / gcd(x,y); return c;}int exgcd(int a, int b, int &x, int &y){ // a > b if(b == 0) { x = 1,y = 0; return a; } int ans = gcd(b,a % b,x,y); int w = x; x = y; y = w - a / b * y; return ans;}bool use[MAXN];void Eular_find_prime(){ for(int i = 2; i <= n; i ++) { if(use[i] == 0) prime[++ cnt] = i; for(int j = 1; j <= cnt && prime[j] * i <= n; j ++) { use[prime[j] * i] = 1; if(i % prime[j] == 0) break; } }}void Erato_find_prime(){ for(int i = 2; i <= n; i ++) if(!use[i]) for(int j = i + i; j <= n; j += i) use[j] = 1; for(int i = 2; i <= n; i ++) if(!use[i]) printf("%d ", i); puts("");}int ksm(int a,int b){ if(b == 0) return 1; int ans = 1; while(b) { if(b & 1) ans *= a; a *= a;b >>= 1; } return ans;}int FTA(int n) //唯一分解定理 { tot = 0; for(int i = 2;i <= n;i ++) { while(n % i == 0) { num[tot ++] = i; n /= i; } } for(int i = 0;i < c;i ++) printf(i == 0 ? "%d" : "*%d" ,num[i]); puts(""); return 0; }
动态规划
背包
void zopack(int vi,int wi){ // 01背包 for(int i = v - vi; i >= 0; i --) dp[i + vi] = max(dp[i + vi],dp[i] + wi); return;}void wqpack(int vi,int wi){ //完全背包 for(int i = 0; i <= v - vi; i ++) dp[i + vi] = max(dp[i + vi],dp[i] + wi); return; }void dcpack(int vi,int wi,int num){ if(vi * num > v) wqpack(vi,wi); int k = 1; while(k < num) { zopack(vi * k,wi * k); num -= k; k <<= 1; } zopack(vi * num,wi * num); return;}int main(){ scanf("%d %d",&n,&v); for(int i = 1; i <= n; i ++) { scanf("%d %d %d",&viv,&w,&num); if(num < 0) wqpack(viv,w); else dcpack(viv,w,num); } for(int i = 0; i <= v; i ++) ans = max(ans,dp[i]); printf("%d\n",ans); return 0;}
最长严格上升子序列
int where(int x){ /* 寻找x在g中的下标 即以x为最小结尾的子序列长度 */ int l = 1,r = n; while(l <= r) { int mid = (l + r) >> 1; if(g[mid] == x) return mid; else if(g[mid] < x) l = mid + 1; else if(g[mid] > x) r = mid - 1; } return l;}int dpdpd(){ memset(g,0x3f,sizeof(g));//极大值 int len = 0; /* 对于原序列中每一个数,寻找g中下标 并用这个数更新g数组与长度 */ for(int i = 1; i <= n; i ++) { int j = where(num[i]); g[j] = min(g[j],num[i]); len = max(len,j); } return len;}
石子归并
int main(){ memset(dp,0x3f,sizeof(dp)); scanf("%d",&n); for(int i = 1; i <= n; i ++) { scanf("%d",&x); sum[i] = sum[i - 1] + x; dp[i][i] = 0; } for(int i = n - 1; i >= 1; i --) for(int j = i + 1; j <= n; j ++) for(int k = i; k <= j - 1; k ++) dp[i][j] = min(dp[i][j],dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]); printf("%d\n",dp[1][n]); return 0;}
树形
没有上司的舞会
图上
伊吹萃香
环形
void dpdpd(){ memset(dp,0,sizeof(dp)); int k = n << 1; for(int i = 2; i <= k; i ++) for(int j = i - 1; j >= 1 && i - j < n; j --) for(int r = j; r < i; r ++) dp[j][i] = max(dp[j][i],dp[j][r] + dp[r + 1][i] + num[j] * num[r + 1] * num[i + 1]),ans = max(ans,dp[j][i]); printf("%d\n",ans);}
套路QAQ
传纸条&&方格取数……
void dpdpd(){ for(int i = 1; i <= m ; i ++) for(int j = 1; j <= n; j ++) for(int x = 1; x <= m; x ++) for(int y = 1; y <= n; y ++) { if(i == x || j == y) dp[i][j][x][y] = max(max(dp[i - 1][j][x - 1][y],dp[i][j - 1][x][y - 1]),max(dp[i][j - 1][x - 1][y],dp[i - 1][j][x][y - 1])) + map[i][j]; else dp[i][j][x][y] = max(max(dp[i - 1][j][x - 1][y],dp[i][j - 1][x][y - 1]),max(dp[i][j - 1][x - 1][y],dp[i - 1][j][x][y - 1])) + map[i][j] + map[x][y]; }}
拦截导弹
int main(){ memset(num,0,sizeof(num)); while(scanf("%d",&num[++ n]) != EOF); //输入处理 n --; for(int i = n - 1; i >= 0; i --) { for(int j = i; j <= n; j ++) if(num[i] < num[j]) up[i] = max(up[i],up[j] + 1); for(int j = i; j <= n; j ++) if(num[i] > num[j]) down[i] = max(down[i],down[j] + 1); } for(int i = 0; i <= n; i ++) { maxs = max(up[i],maxs); mins = max(down[i],mins); } printf("%d\n%d",mins + 1,maxs); return 0;}
尼克的任务
输出第一个
void dpdpd(){ int xc = k; for(int i = n; i >= 1; i --) { if(num[xc].l == i)//有>= 1的任务 { while(num[xc].l == i) { if(dp[i] < dp[i + num[xc].t]) dp[i] = dp[i + num[xc].t]; xc --; } } else if(num[xc].l != i)//没有任务 dp[i] = dp[i + 1] + 1; }
1 0
- Dear 时继
- DEAR
- sorry dear
- my dear
- dear diary
- Dear Diary
- Dear 林深时见鹿
- Dear 素时雨
- Dear 南来北往
- Dear 司晨
- Dear 清明
- Bye, my dear programming!
- sorry dear (2)
- A Dear John Letter
- Dear Mom and Dad
- My dear jewelries
- Dear diary moment
- Dear,I Love you!
- Java项目开发问题(-)在前端页面中==与eq的区别
- 5个实用的shell脚本面试题和答案
- S3C6410的MMU学习
- JSP的七个动作元素
- facebook Web javascript sdk 登陆获取个人信息
- Dear 时继
- 基于gstreamer的视频转发
- VB6利用win32API画玫瑰花算法
- eclipse 常用快捷键
- Checkout conflict with files: src/main/resources/jeesite.properties Checkout
- Android自定义ImageView:在图片上添加一个图层
- mysql_性能优化_3_优化数据对象
- js数组-控制先合并后去重(基于上篇-js去重方法)
- IOS开发之----两种保存用户名和密码实现记住密码库的方法