
例题地址
设
f
i
,
j
f_{i,j}
fi,j为前i个物品使用了j的体积
#include完全背包问题#include using namespace std; int n,m,v[1010],w[1010],f[1010][1010]; int main(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> v[i] >> w[i]; for(int j=0;j<=m;j++){ if(j-v[i]<0){ f[i][j] = f[i-1][j]; }else{ f[i][j] = max(f[i-1][j],f[i-1][j-v[i]]+w[i]); } } } cout << f[n][m]; }
例题地址
设
f
i
,
j
f_{i,j}
fi,j为前i个物品使用了j的体积
然后优化了时间和空间
#include2.图论 二叉树遍历#include using namespace std; int n,m,v[1010],w[1010],f[1010]; int main(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> v[i] >> w[i]; for(int j = v[i] ; j<=m ;j++){ f[j] = max(f[j],f[j-v[i]]+w[i]); } } cout << f[m] << endl; return 0; }
输入先序遍历和中序遍历,输出后序遍历
#include线段树1#include using namespace std; void dfs(string s1,string s2) { int len = s2.find(s1[0]); if(len == s2.npos)return; string s1_1 = s1.substr(1,len); string s1_2 = s1.substr(len + 1); string s2_1 = s2.substr(0,len); string s2_2 = s2.substr(len + 1); dfs(s1_1,s2_1); dfs(s1_2,s2_2); cout << s1[0]; } int main() { string s1,s2; cin >> s1 >> s2; dfs(s1,s2); cout << endl; }
题目地址
单点修改,区间查询
#include线段树2using namespace std; int n,m,sum[400010],a[400010]; int p(int x){ sum[x] = min(sum[x*2],sum[x*2+1]); } // 初始化函数 void b(int l,int r,int rt){ if(l==r){ sum[rt] = a[l];return ; } int mid = l+r>>1; b(l,mid,rt*2); b(mid+1,r,rt*2+1); p(rt); } // 修改函数 void xx(int l,int r,int rt,int x,int d){ if(l==r){ sum[rt] = d; return ; } int mid = l+r>>1; if( x<=mid) xx(l,mid,rt*2,x,d); else xx(mid+1,r,rt*2+1,x,d); p(rt); } // 查询区间 int c(int l,int r,int rt,int x,int y){ if(l>=x and y>=r){ return sum[rt]; } int mid = l+r>>1; int ans=1234567890; if(x<=mid){ ans = min(ans,c(l,mid,rt*2,x,y)); } if(y>mid){ ans = min(ans,c(mid+1,r,rt*2+1,x,y)); } return ans; } int main(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> a[i]; } b(1,n,1); for(int i=1;i<=m;i++){ int p,x,y; cin >> p >> x >> y; if(p==1){ cout << c(1,n,1,x,y) << ' '; }else{ xx(1,n,1,x,y); } } return 0; }
题目地址
区间修改区间查询
#include并查集#define int long long using namespace std; int s[4000010],a[1000010],f[4000010],n,m; void upd(int rt){ s[rt] = s[rt<<1]+s[(rt<<1)+1]; // s[rt] += ; } void updd(int rt,int x,int y){ if(f[rt]){ f[rt<<1] += f[rt]; f[(rt<<1)+1] += f[rt]; s[rt<<1] += x*f[rt]; s[(rt<<1)+1] += y*f[rt]; f[rt] = 0; } } void init(int rt=1,int l=1,int r=n){ if(l==r){ s[rt] = a[l]; return; } int mid = l+r>>1; init(rt<<1,l,mid); init((rt<<1)+1,mid+1,r); upd(rt); } int get(int x,int y,int rt=1,int l=1,int r=n){ if(x<=l and r<=y){ return s[rt]; } int ans=0,mid = l+r>>1; updd(rt,mid-l+1,r-mid); if(x<=mid) ans+=get(x,y,rt<<1, l,mid); if(y>mid) ans+=get(x,y,(rt<<1)+1,mid+1,r); upd(rt); return ans; } void add(int x,int y,int z,int rt=1,int l=1,int r=n){ if(x<=l and r<=y){ s[rt] += (r-l+1)*z; f[rt] += z; return ; } int mid = l+r>>1; updd(rt,mid-l+1,r-mid); if(x<=mid) add(x,y,z,rt<<1, l,mid); if(y>mid) add(x,y,z,(rt<<1)+1,mid+1,r); upd(rt); return ; } signed main(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> a[i]; } init(); // cout << "OK" << endl; for(int i=1;i<=m;i++){ int op,x,y,z; cin >> op; if(op==1){ cin >> x >> y >> z; add(x,y,z); }else{ cin >> x >> y; cout << get(x,y) << endl; } } }
题目地址
两种操作:
#include树状数组#define int long long using namespace std; int n,m; struct node{ // 这个就是并查集的结构体 int fa[10010]; void init(){ // 初始化函数,让所有点指向自己 for(int i =0;i<=n;i++){ fa[i] = i; } } int get(int x){ // 获取第x的父节点 if(fa[x]==x){// 如果是自己就说明到头了,返回x或fa[x] return x; } return fa[x] = get(fa[x]); // 否则就递归下去 } void add(int x,int y){ // 合并函数,合并两个集合 fa[get(x)] = get(y); } }; node s; signed main(){ // 主函数 cin >> n >> m; s.init(); for(int i=1;i<=m;i++){ int op,x,y; cin >> op >> x >> y; // 读入,op代表z if(op==1){ s.add(x,y); }else{ if(s.get(x)==s.get(y)){ // 判断x和y是否在同一个集合里 cout << "Y" << endl; }else{ cout << "N" << endl; } } } }
题目地址
单点修改区间查询
#include树的重心using namespace std; const int N = 500010; int n,m,a[N],c[N]; void add(int k, int i){ while(i<=n){ c[i]+=k; i+=(i&-i); } } int sum(int num){ int cnt = 0; while(num){ cnt+=c[num]; num-=(num&-num); } return cnt; } int main(){ cin >> n >> m; for(int i=1;i<=n;i++){ cin >> a[i]; add(a[i],i); } int f,x,y; while(m--){ scanf("%d%d%d",&f,&x,&y); if(f==1){ add(y,x); }else{ cout << sum(y)-sum(x-1) << endl; } } return 0; }
题目地址
输入一个n-1条边的树,求哪一个点离其他点的总距离最近的点输出
#include#define int long long using namespace std; int n; vector g[50010]; int ans=1234567890; int s[50010],r=1; int size[50010]; void dfs(int u,int fa){ size[u] = 1; int m=0; for(int i=0;i n; // for(int i=1;i<=n;i++){ // size[i] = 1; // } int x,y; for(int i=1;i<=n-1;i++){ cin >> x >> y; g[x].push_back(y); g[y].push_back(x); } dfs(1,0); sort(s+1,s+r); for(int i=1;i 本文将持续更新,建议收藏!