8.11-8.16:usaco
summary:57
bzoj1741:裸二分图最大匹配
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=10005; struct edge{ int to;edge *next; }; edge es[maxn],*pt=es,*head[nmax]; bool vis[nmax];int match[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; } bool dfs(int x){ qwq(x) if(!vis[o->to]){ vis[o->to]=1; if(!match[o->to]||dfs(match[o->to])){ match[o->to]=x;return true; } } return false; } int main(){ int n=read(),m=read(),u,v; rep(i,1,m) u=read(),v=read(),add(u,v+n); int ans=0; rep(i,1,n){ clr(vis,0); if(dfs(i)) ans++; } printf("%d\n",ans); return 0; }
bzoj1742:dp题。我想的总是点的情况,比如到当前是那一步用步数来转移还是不行的。需要考虑的转换情况的这段区间的情况,不要局限于死思维!!! 其实跟以前做过的差不多,枚举区间的长短。为什么想不出来!!!
dp[j][0]改变了居然样例能过。。。然后就WA了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; int dp[nmax][2],a[nmax]; int main(){ int n=read(),s=read(); rep(i,1,n) a[i]=read(); sort(a+1,a+n+1); rep(i,1,n) dp[i][0]=dp[i][1]=abs(s-a[i])*n; rep(i,2,n){ for(int j=1;j+i-1<=n;j++){ int k=j+i-1,tmp=dp[j][0]; dp[j][0]=min(dp[j+1][0]+(a[j+1]-a[j])*(n-i+1),dp[j+1][1]+(a[k]-a[j])*(n-i+1)); dp[j][1]=min(dp[j][1]+(a[k]-a[k-1])*(n-i+1),tmp+(a[k]-a[j])*(n-i+1)); } } printf("%d\n",min(dp[1][0],dp[1][1])); return 0; }
bzoj1750:dp。。。每个点都可以转或者不转。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=1005; const int maxn=35; int dp[nmax][maxn],a[nmax]; void maxs(int &a,int b){ if(a<b) a=b; } int main(){ int n,m;scanf("%d%d",&n,&m); rep(i,1,n) scanf("%d",&a[i]); rep(i,1,n){ rep(j,0,i){ if(j>m) break; if(j) dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+(j%2+1==a[i]); else dp[i][j]=dp[i-1][j]+(j%2+1==a[i]); } } rep(i,1,m) maxs(dp[n][i],dp[n][i-1]); printf("%d\n",dp[n][m]); return 0; }
bzoj1752:最短路。。。我。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=100005; const int inf=0x7f7f7f7f; struct edge{ int to,dist;edge *next; }; edge es[maxn],*pt=es,*head[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++; } int dist[nmax]; struct node{ int x,dist; node(int x,int dist):x(x),dist(dist){}; bool operator<(const node&rhs)const{ return dist>rhs.dist;} }; priority_queue<node>q; void dijkstra(){ clr(dist,0x7f);dist[1]=0;q.push(node(1,0)); while(!q.empty()){ node o=q.top();q.pop(); int tx=o.x,td=o.dist; if(dist[tx]!=td) continue; qwq(tx) if(dist[o->to]>td+o->dist){ dist[o->to]=td+o->dist;q.push(node(o->to,dist[o->to])); } } } int main(){ int m=read(),n=read(),u,v,d; rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d); dijkstra(); printf("%d\n",dist[n]); return 0; }
bzoj1753:我、、、
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } int a[1000005]; int main(){ int n=read(); rep(i,1,n) a[i]=read(); sort(a+1,a+n+1); printf("%d\n",a[(n+1)>>1]); return 0; }
bzoj1754:高精度乘法。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) int a[45],b[45],ans[100]; char s[45],t[45]; int main(){ scanf("%s%s",s+1,t+1); int lena=strlen(s+1),lenb=strlen(t+1),len=lena+lenb; rep(i,1,lena) a[i]=s[lena-i+1]-'0'; rep(i,1,lenb) b[i]=t[lenb-i+1]-'0'; rep(i,1,lena) rep(j,1,lenb){ ans[i+j-1]+=a[i]*b[j]; if(ans[i+j-1]>9) { ans[i+j]+=ans[i+j-1]/10; ans[i+j-1]%=10; } } if(ans[lenb+lena-1]>9) { ans[lena+lenb]=ans[lena+lenb-1]/10; ans[lena+lenb-1]%=10; len++; } while(ans[len]==0) len--; dwn(i,len,1) printf("%d",ans[i]);printf("\n"); return 0; }
bzoj1755:我。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) int main(){ double a,b;int n; scanf("%lf%lf%d",&a,&b,&n); a/=100;a+=1; rep(i,1,n) b*=a; int ans=(int)b; printf("%d\n",ans); return 0; }
bzoj1770:高斯消元然后爆搜自由元以前写过。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bitset> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=40; const int inf=0x7f7f7f7f; bitset<nmax>a[nmax]; void gauss(int n,int m){ rep(i,1,n){ int j;for(j=i;j<=n&&!a[j][i];j++) if(j<n) continue; if(j!=i) swap(a[i],a[j]); rep(j,i+1,n) if(a[j][i]) a[j]^=a[i]; } } int res=inf,ans[nmax],tot=0; int n,m; void mins(int &a,int b){ if(a>b) a=b; } void dfs(int x){ if(tot>=res) return ; if(!x) { mins(res,tot);return ; } if(a[x][x]){ int t=a[x][n+1]; rep(i,x+1,n) if(a[x][i]) t^=ans[i]; ans[x]=t; if(t) tot++; dfs(x-1); if(t) tot--; }else{ ans[x]=0;dfs(x-1); ans[x]=1;tot++;dfs(x-1);tot--; } } int main(){ n=read(),m=read();int u,v; rep(i,1,n) a[i][i]=a[i][n+1]=1; rep(i,1,m) u=read(),v=read(),a[u][v]=a[v][u]=1; gauss(n,n+1);dfs(n); printf("%d\n",res); return 0; }
洛谷3793:输出第n组勾股数。不会。。。在网上找勾股数的规律被我找到了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(ll i=s;i<=t;i++) #define ll long long int main(){ ll n; while(scanf("%lld",&n)==1){ n+=2; if(n%2){ printf("%lld %lld %lld\n",n,(n*n-1)/2,(n*n+1)/2); }else printf("%lld %lld %lld\n",n,(n/2)*(n/2)-1,(n/2)*(n/2)+1); } return 0; }
洛谷3832:田忌赛马。不会。。。神贪心!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0,f=1;char c=getchar(); while(!isdigit(c)) { if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } const int nmax=5005; int a[nmax],b[nmax]; int main(){ int n=read(); rep(i,1,n) a[i]=read(); rep(i,1,n) b[i]=read(); sort(a+1,a+n+1);sort(b+1,b+n+1); int l=1,s=1,r=n,t=n,ans=0; while(l<=r){ if(a[l]>b[s]) ans+=200,l++,s++; else if(a[r]>b[t]) ans+=200,r--,t--; else ans+=(a[l]!=b[t])*(-200),++l,--t; } printf("%d\n",ans); return 0; }
bzoj1774:将点权排序后用floyed就好了。没有考虑重边的情况wa了一次。看清楚题!!!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=255; int dist[nmax][nmax],ans[nmax][nmax],w[nmax]; struct node{ int w,id; bool operator<(const node&rhs)const{ return w<rhs.w;} }; node ns[nmax]; int main(){ int n=read(),m=read(),q=read(),u,v,d; rep(i,1,n) w[i]=ns[i].w=read(),ns[i].id=i; sort(ns+1,ns+n+1); clr(dist,0x3f);clr(ans,0x3f); rep(i,1,n) dist[i][i]=ans[i][i]=0; rep(i,1,m) u=read(),v=read(),d=read(),dist[u][v]=dist[v][u]=min(dist[u][v],d); rep(tk,1,n){ int k=ns[tk].id; rep(i,1,n) rep(j,1,n) { dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]); ans[i][j]=min(ans[i][j],dist[i][j]+max(ns[tk].w,max(w[i],w[j]))); } } rep(i,1,q) u=read(),v=read(),printf("%d\n",ans[u][v]); return 0; }
bzoj1782:树链剖分O(nlogn)还是可以写的。看了一下题解可以用类似dfs序+bit解决。子树消掉+bit的经典应用。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const int inf=0x7fffffff; int sum[nmax<<2],n,id[nmax],ans[nmax]; struct edge{ int to;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } void update(int x,int w){ for(int i=x;i<=n;i+=(i&-i)) sum[i]+=w; } int query(int x){ int ans=0; for(int i=x;i;i-=(i&-i)) ans+=sum[i]; return ans; } void dfs(int x,int fa){ int t=id[x]; ans[t]=query(id[x]);update(id[x],1); qwq(x) if(o->to!=fa) dfs(o->to,x); update(id[x],-1); } int main(){ n=read();int u,v; rep(i,1,n-1) u=read(),v=read(),add(u,v); rep(i,1,n) u=read(),id[u]=i; dfs(1,0); rep(i,1,n) printf("%d\n",ans[i]); return 0; }
bzoj1827:树形dp。想处理子树的情况,再利用父结点处理非子树的情况就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define ll long long int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const ll inf=1e18; ll w[nmax],size[nmax]; ll f[nmax],g[nmax],n,sum=0; struct edge{ int to;ll dist;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v,ll d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++; } void dfs(int x,int fa){ size[x]=w[x]; qwq(x) if(o->to!=fa){ dfs(o->to,x);size[x]+=size[o->to]; f[x]+=f[o->to]+size[o->to]*o->dist; } } void DFS(int x,int fa){ qwq(x) if(o->to!=fa){ g[o->to]=f[o->to]+g[x]-f[o->to]-size[o->to]*o->dist+(sum-size[o->to])*o->dist; DFS(o->to,x); } } int mins(ll &a,ll b){ if(a>b) a=b; } int main(){ n=read();int u,v;ll d; rep(i,1,n) w[i]=read(),sum+=w[i]; rep(i,1,n-1) u=read(),v=read(),d=read(),add(u,v,d); dfs(1,0); g[1]=f[1]; DFS(1,0); ll ans=inf; rep(i,1,n) mins(ans,g[i]); printf("%lld\n",ans); return 0; }
bzoj3196:看题目肯定是二分答案。那么二分答案后贪心判断!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=505; const int inf=0x7fffffff; int map[nmax][nmax],n,m,A,B; int check(int s,int t,int x){ int cur=1,sum,ans=0;bool flag; while(1){ sum=0;flag=false; rep(i,cur,m){ sum+=map[t][i]-map[s][i]; if(sum>=x) { flag=true;ans++;cur=i+1;break; } } if(cur>m||!flag) break; } return ans; } bool pd(int x){ int cur=1,ans=0;bool flag; while(1){ flag=false; rep(i,cur,n) { if(check(cur-1,i,x)>=B){ flag=true;ans++;cur=i+1;break; } } if(cur>n||!flag) break; } return ans>=A; } int main(){ n=read(),m=read(),A=read(),B=read(); rep(i,1,n) rep(j,1,m) map[i][j]=map[i-1][j]+read(); int l=0,r=inf,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(pd(mid)) ans=mid,l=mid+1; else r=mid-1; } printf("%d\n",ans); return 0; }
bzoj2060:树形dp
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; const int inf=0x7f7f7f7f; int dp[nmax][2]; struct edge{ int to;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } void dfs(int x,int fa){ dp[x][1]=1; qwq(x) if(o->to!=fa){ int to=o->to;dfs(to,x); dp[x][0]+=max(dp[to][0],dp[to][1]); dp[x][1]+=dp[to][0]; } } int main(){ int n=read(),u,v; rep(i,1,n-1) u=read(),v=read(),add(u,v); dfs(1,0); printf("%d\n",max(dp[1][1],dp[1][0])); return 0; }
bzoj2274:dp.f[i]+=f[j],sum[i]-sum[j]>=0;O(n2) orz又跪了 =>加树状数组搞一下就行了!!!(对bit有点了解了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0,f=1;char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } const int nmax=100005; const int mod=1000000009; int a[nmax],b[nmax],sum[nmax<<2],dp[nmax],n,N; int query(int x){ int ans=0; for(int i=x;i;i-=(i&-i)) { ans=(ans+sum[i])%mod; } return ans; } void insert(int x,int w){ for(int i=x;i<=N;i+=(i&-i)) sum[i]=(sum[i]+w)%mod; } int main(){ n=read();int u; rep(i,1,n) u=read(),b[i]=b[i-1]+u,a[i]=b[i]; b[0]=0;sort(b,b+n+1); N=unique(b,b+n+1)-b; u=lower_bound(b,b+N,0)-b; insert(++u,1); rep(i,1,n) { u=lower_bound(b,b+N,a[i])-b; dp[i]=query(++u); insert(u,dp[i]); } printf("%d\n",dp[n]); return 0; } /* 5 -1 -1 -1 -1 -1*/
bzoj2442:开始的时候想了贪心无解。。然后dp!。嘛o(nk)的还是很容易的。。。学到了单调队列优化dp。。而且连dp[i][0],dp[i][1]都可以省略了。用了fread果然快了挺多的。。。好神啊啊啊 ps:滑块不就用单调队列么2333
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;++i) #define dwn(i,s,t) for(int i=s;i>=t;--i) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long char buf[1000005],*ptr=buf-1; ll read(){ ll x=0;char c=*++ptr; while(!isdigit(c)) c=*++ptr; while(isdigit(c)) x=x*10+c-'0',c=*++ptr; return x; } const int nmax=100005; ll dp[nmax],sum[nmax],q[nmax]; int main(){ fread(buf,1,1000000,stdin); ll n=read(),k=read(); rep(i,1,n) sum[i]=sum[i-1]+read(); int l=1,r=1; rep(i,1,n){ while(l<=r&&q[l]<i-k) ++l; if(i<=k) dp[i]=sum[i]; else dp[i]=dp[q[l]-1]+sum[i]-sum[q[l]]; while(l<=r&&dp[q[r]-1]-sum[q[r]]<dp[i-1]-sum[i]) --r; q[++r]=i; } printf("%lld\n",dp[n]); return 0; }
bzoj2591:嘛是树形dp嘛。。。不过居然写了很久!!!没有将细节考虑清楚前不要写!写到一半发现有误停下来全部想清楚再写!!!不要这个改一下那个改一下!!! 哦树形dp还是先处理子树的情况然后再有父结点弄出非子树的情况。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const int inf=0x7f7f7f7f; int f[nmax][25],g[nmax][25],w[nmax],n,K; struct edge{ int to;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } void dfs(int x,int fa){ f[x][0]=w[x]; qwq(x) if(o->to!=fa){ dfs(o->to,x); rep(i,1,K) f[x][i]+=f[o->to][i-1]; } } void DFS(int x,int fa){ g[x][0]=w[x];g[x][1]=f[x][1]+w[fa]; rep(i,2,K) g[x][i]=f[x][i]+g[fa][i-1]-f[x][i-2]; qwq(x) if(o->to!=fa) DFS(o->to,x); } int main(){ n=read(),K=read();int u,v; rep(i,1,n-1) u=read(),v=read(),add(u,v); rep(i,1,n) w[i]=read(); dfs(1,0); rep(i,0,K) g[1][i]=f[1][i]; qwq(1) DFS(o->to,1); rep(i,1,n) { rep(j,0,K) g[i][j]+=g[i][j-1]; printf("%d\n",g[i][K]); } return 0; }
bzoj3050:测了自己手造数据就直接交了。output limited error。。。注意注意注意中间输出要删掉中间输出要删掉中间输出要删掉!而且最好肉眼看一下有没有写错QAQ。 还有还有还有!有时候编译器会出现诡异错误按f9的时候直接整个程序就没了!所以我们要先保存好文件再开始写!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define lson l,mid,x<<1 #define rson mid+1,r,x<<1|1 int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=2000005; const int inf=0x7f7f7f7f; int lmax[nmax],omax[nmax],rmax[nmax],col[nmax]; char s[5]; int n; void build(int l,int r,int x){ lmax[x]=rmax[x]=omax[x]=r-l+1;col[x]=-1; if(l==r) return ; int mid=(l+r)>>1;build(lson);build(rson); } void pushdown(int x,int cnt){ if(col[x]!=-1){ col[x<<1]=col[x<<1|1]=col[x]; lmax[x<<1]=rmax[x<<1]=omax[x<<1]=col[x]?0:cnt-(cnt>>1); lmax[x<<1|1]=rmax[x<<1|1]=omax[x<<1|1]=col[x]?0:cnt>>1; col[x]=-1; } } void pushup(int x,int cnt){ lmax[x]=lmax[x<<1]==cnt-(cnt>>1)?lmax[x<<1]+lmax[x<<1|1]:lmax[x<<1]; rmax[x]=rmax[x<<1|1]==(cnt>>1)?rmax[x<<1|1]+rmax[x<<1]:rmax[x<<1|1]; omax[x]=max(rmax[x<<1]+lmax[x<<1|1],max(omax[x<<1],omax[x<<1|1])); } int query(int p,int l,int r,int x){ if(r-l+1==p) return l; pushdown(x,r-l+1); int mid=(l+r)>>1; if(omax[x<<1]>=p) return query(p,lson); if(rmax[x<<1]+lmax[x<<1|1]>=p) return mid-rmax[x<<1]+1; return query(p,rson); } void update(int tl,int tr,int p,int l,int r,int x){ if(tl<=l&&tr>=r){ col[x]=p; lmax[x]=rmax[x]=omax[x]=p?0:r-l+1; return ; } pushdown(x,r-l+1); int mid=(l+r)>>1; if(tl<=mid) update(tl,tr,p,lson); if(tr>mid) update(tl,tr,p,rson); pushup(x,r-l+1); } int main(){ n=read();int m=read(),u,v,ans=0; build(1,n,1); rep(i,1,m) { scanf("%s",s); if(s[0]=='A'){ u=read(); if(omax[1]<u) ans++; else { v=query(u,1,n,1); update(v,v+u-1,1,1,n,1); } }else{ u=read(),v=read(); update(u,v,0,1,n,1); } } printf("%d\n",ans); return 0; }
bzoj3407:背包dp。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } int a[505],f[45005]; int main(){ int m=read(),n=read(); rep(i,1,n) a[i]=read(); f[0]=1; rep(i,1,n) dwn(j,m,a[i]) f[j]|=f[j-a[i]]; dwn(i,m,0) if(f[i]){ printf("%d\n",i);return 0; } return 0; }
bzoj3445:删掉的肯定是最短路中的边。。。枚举一下就好了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=255; const int maxn=250005; struct edge{ int to,dist,id;edge *next; }; edge es[maxn<<1],*pt=es,*head[nmax]; int n,m,dist[nmax],pre[nmax],fa[nmax]; void add(int u,int v,int d,int id){ pt->to=v;pt->dist=d;pt->id=id;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->id=id;pt->next=head[v];head[v]=pt++; } struct node{ int x,dist; node(int x,int dist):x(x),dist(dist){}; node(){}; bool operator<(const node&rhs)const{ return dist>rhs.dist;} }; priority_queue<node>q; void maxs(int &a,int b){ if(a<b) a=b; } void dijkstra(){ clr(dist,0x7f);dist[1]=0;q.push(node(1,0)); node o;int tx,td; while(!q.empty()){ o=q.top();q.pop(); tx=o.x;td=o.dist; if(dist[tx]!=td) continue; qwq(tx) if(dist[o->to]>td+o->dist){ dist[o->to]=td+o->dist;pre[o->to]=tx;fa[o->to]=o->id; q.push(node(o->to,dist[o->to])); } } } void DIJKSTRA(){ clr(dist,0x7f);dist[1]=0;q.push(node(1,0)); node o;int tx,td; while(!q.empty()){ o=q.top();q.pop(); tx=o.x;td=o.dist; if(dist[tx]!=td) continue; qwq(tx) if(dist[o->to]>td+o->dist){ dist[o->to]=td+o->dist; q.push(node(o->to,dist[o->to])); } } } int main(){ n=read(),m=read(); int u,v,d,tmp,temp; rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d,i); dijkstra();tmp=dist[n]; for(int i=n;i!=1;i=pre[i]) { u=pre[i]; qwq(u) if(o->id==fa[i]) o->dist<<=1; qwq(i) if(o->id==fa[i]) o->dist<<=1; DIJKSTRA();maxs(temp,dist[n]); qwq(u) if(o->id==fa[i]) o->dist>>=1; qwq(i) if(o->id==fa[i]) o->dist>>=1; } printf("%d\n",temp-tmp); return 0; }
bzoj3048:二分答案然后判断?k(n-k)最坏的情况下50000*50000. 嗯还是有暴力分的。sad又跪了=> 用类似单调队列的方法扫一遍就好了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; int a[nmax],b[nmax],cnt[nmax]; bool vis[nmax]; void maxs(int &a,int b){ if(a<b) a=b; } int main(){ int n=read(),k=read(); rep(i,1,n) a[i]=b[i]=read(); sort(b+1,b+n+1); int m=unique(b+1,b+n+1)-b; rep(i,1,n) a[i]=lower_bound(b+1,b+m+1,a[i])-b; int l=1,r=1,sum=0,ans=1;clr(vis,0); while(r<=n){ while(vis[a[r]]||(!vis[a[r]])&&sum<k+1){ if(vis[a[r]]) maxs(ans,++cnt[a[r]]); else vis[a[r]]=1,++cnt[a[r]],sum++; if(++r>n) break; } if(!(--cnt[a[l]])) sum--,vis[a[l]]=0; l++; } printf("%d\n",ans); return 0; }
❤bzoj1685:不懂系列!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=25; struct node{ int w,b; bool operator<(const node&rhs)const{ return w<rhs.w;} }; node ns[nmax]; int main(){ int n=read(),m=read(); rep(i,1,n) ns[i].w=read(),ns[i].b=read(); sort(ns+1,ns+n+1); int ans=0,t,temp; while(1){ temp=m; dwn(i,n,1) { t=min(temp/ns[i].w,ns[i].b); temp-=t*ns[i].w; ns[i].b-=t; } rep(i,1,n) if(ns[i].b>0&&temp>0){ ns[i].b--; temp-=ns[i].w; }//没办法了就扔多一个硬币给他,注意一个硬币就好了。 if(temp<=0) ans++; else break; } printf("%d\n",ans); return 0; }
bzoj1680:。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; const int inf=0x7f7f7f7f; struct node{ int w,nd; }; node ns[nmax]; void mins(int &a,int b){ if(a>b) a=b; } int main(){ int n=read(),s=read(); rep(i,1,n) ns[i].w=read(),ns[i].nd=read(); ll ans=0;int nmin=inf; rep(i,1,n){ mins(nmin,ns[i].w); ans+=ns[i].nd*nmin; nmin+=s; } printf("%lld\n",ans); return 0; }
bzoj1676:差分序列就好了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define dwn(i,s,t) for(int i=s;i>=t;i--) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=2005; int a[nmax]; void maxs(int &a,int b){ if(a<b) a=b; } int main(){ int n=read(),fa=read(),fb=read(),D=read(),lft=fa-fb,u,v,d,tmp=0,temp=0; rep(i,1,n) { u=read(),v=read(); a[v]++,a[u-1]--,maxs(tmp,v); } dwn(i,tmp,1){ temp+=a[i]; if(i<=D) lft-=temp; if(!lft) { printf("%d\n",i);break; } } return 0; }
bzoj1675:搜索+hash判重!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=100005; const int mod=100007; int head[mod],next[nmax],a[nmax],ans=0; char map[6][6];bool vis[6][6]; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; void print(int x){ rep(i,1,5){ rep(j,1,5) printf("%d",x&1),x>>=1;printf("\n"); } } void dfs(int x,int y,int hn,int jn,int pre){ if(map[x][y]=='H') hn++;else jn++; if(hn>3) return ; pre+=(1<<((x-1)*5+y-1)); int tmp=pre%mod;bool f=true; for(int i=head[tmp];i;i=next[i]) if(a[i]==pre) f=false; if(f) { a[++a[0]]=pre;next[a[0]]=head[tmp];head[tmp]=a[0]; } else return ; if(hn+jn==7) ans++; else{ vis[x][y]=1; int tx,ty; rep(i,1,5) rep(j,1,5) if(vis[i][j]) rep(k,1,4) { tx=i+xx[k];ty=j+yy[k]; if(tx<1||ty<1||tx>5||ty>5||vis[tx][ty]) continue; dfs(tx,ty,hn,jn,pre); } vis[x][y]=0; } } int main(){ rep(i,1,5) scanf("%s",map[i]+1); rep(i,1,5) rep(j,1,5) dfs(i,j,0,0,0); printf("%d\n",ans); return 0; }
bzoj1674:bfs。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=50005; const int inf=0x7f7f7f7f; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; } int q[nmax],dist[nmax]; int main(){ int N=read(),T=read(),u,v; rep(i,1,N) { u=read(),v=read(); add(u,v); } int l=1,r=1;q[1]=1; while(l<=r){ u=q[l];l++; qwq(u) if(!dist[o->to]){ dist[o->to]=dist[u]+1; q[++r]=o->to; if(o->to==T) { printf("%d\n",dist[o->to]+1); return 0; } } } printf("-1\n"); return 0; }
洛谷3936:挖坑。。。这道题我只写了三十分,mle了而且不mle的话也应该是50分的啊。。。我用hash判重+dp。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll unsigned long long const int nmax=1001; ll pre[nmax][nmax],suf[nmax][nmax],a[nmax]; bool dp[nmax][nmax]; char s[nmax]; int main(){ scanf("%s",s+1); int len=strlen(s+1); rep(i,1,len) a[i]=s[i]-'a'+1; rep(i,1,len) { pre[i][i]=a[i]; rep(j,i+1,len) pre[i][j]=pre[i][j-1]*26+a[j]; } dwn(i,len,1){ suf[i][i]=a[i]; dwn(j,i-1,1) suf[j][i]=suf[j+1][i]*26+a[j]; } rep(i,1,len) dp[i][i]=1,dp[i][i+1]=a[i]==a[i+1]?1:0; rep(i,2,len-1) rep(j,1,len-i) { int tmp=i/2; if(i%2==0) tmp--; if(pre[j][j+tmp]==suf[j+i-tmp][j+i]) dp[j][j+i]=1; } int cur=1,ans=0; while(cur<=len){ dwn(i,len,cur) if(dp[cur][i]) { ans++;cur=i+1; break; } if(cur>len) break; } printf("%d\n",ans); return 0; }
洛谷3868:康托展开就好了
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(ll i=s;i<=t;i++) #define dwn(i,s,t) for(ll i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long ll read(){ ll x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const ll mod=1000000007; ll a[nmax]; bool vis[nmax]; int main(){ ll n=read(),u,v,d,tmp,temp; a[0]=1; rep(i,1,n) a[i]=(a[i-1]*i)%mod; ll ans=1; rep(i,1,n) { u=read();v=0; rep(j,1,u-1) if(!vis[j]) v++; vis[u]=1; ans=(ans+(v*a[n-i])%mod)%mod; } printf("%lld\n",ans); return 0; }
bzoj2018:这
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(ll i=s;i<=t;i++) #define dwn(i,s,t) for(ll i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long ll read(){ ll x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1500005; struct node{ ll w,u; bool operator<(const node&rhs)const{ return u>rhs.u||u==rhs.u&&w<rhs.w;} }; node ns[nmax]; int main(){ ll n=read(),a=read(),b=read(),c=read(),d=read(),e=read(),f=read(),g=read(),h=read(),m=read(),tmp,temp; rep(i,0,n*3-1) { tmp=(i*i)%d; ns[i].w=((a*i%d)*(tmp*tmp%d)%d+b*tmp%d+c)%d; tmp=(i*i)%h; ns[i].u=((e*i%h)*(tmp*tmp%h)%h+(f*tmp%h)*i%h+g)%h; } sort(ns,ns+n*3); ll ans=0; rep(i,0,n-1) ans=(ans+ns[i].w)%m; printf("%lld\n",ans); return 0; }
❤bzoj3890:拓扑图上的dp。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bitset> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=10005; bitset<maxn>f[nmax],g[nmax]; struct edge{ int to,da,db;edge *next; }; edge es[maxn],*pt=es,*head[nmax]; int in[nmax],q[nmax]; void add(int u,int v,int d,int w){ pt->to=v;pt->da=d;pt->db=w;pt->next=head[u];head[u]=pt++; } int main(){ int n=read(),m=read(),u,v,d,w,tmp,temp; rep(i,1,m) u=read(),v=read(),d=read(),w=read(),add(u,v,d,w),in[v]++; int l=1,r=0; rep(i,1,n) if(!in[i]) q[++r]=i; f[1][0]=g[1][0]=1; while(l<=r){ u=q[l++]; qwq(u) { f[o->to]|=f[u]<<o->da; g[o->to]|=g[u]<<o->db; if(!--in[o->to]) q[++r]=o->to; } } rep(i,0,10000) if(f[n][i]&&g[n][i]){ printf("%d\n",i);return 0; } printf("IMPOSSIBLE\n"); return 0; }
bzoj3480:先背包dp预处理后递推就好了
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=100005; const int inf=0x7f7f7f7f; int a[nmax],dp[maxn]; void mins(int &a,int b){ if(a>b) a=b; } int main(){ int n=read(),m=read(); rep(i,1,m) a[i]=read(); clr(dp,0x7f);dp[0]=0; rep(i,1,n) rep(j,a[i],100000) mins(dp[j],dp[j-a[i]]+1); rep(i,1,n) a[i]=read(); int cur=1; while(!a[cur]&&cur<=n) cur++; int ans=dp[a[cur]]; rep(i,cur+1,n) ans+=dp[a[i]+1-a[i-1]]; printf("%d\n",ans); return 0; }
bzoj3394:floyed一下就好了。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=505; const int inf=0x7f7f7f7f; int dist[nmax][nmax],a[nmax]; void mins(int &a,int b){ if(a>b) a=b; } int main(){ int n=read(),p=read(),m=read(),u,v,d; rep(i,1,p) a[i]=read(); clr(dist,0x7f); rep(i,1,n) dist[i][i]=0; rep(i,1,m) u=read(),v=read(),dist[u][v]=dist[v][u]=read(); rep(k,1,n) rep(i,1,n) rep(j,1,n) if(dist[i][k]!=inf&&dist[k][j]!=inf) mins(dist[i][j],dist[i][k]+dist[k][j]); int ans=inf,res,tmp; rep(i,1,n){ tmp=0; rep(j,1,p) tmp+=dist[i][a[j]]; if(tmp<ans) ans=tmp,res=i; } printf("%d\n",res); return 0; }
bzoj3389:最少多少个区间就能够覆盖整个区间。贪心。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=25005; struct node{ int l,r; bool operator<(const node&rhs)const{ return l<rhs.l||l==rhs.l&&r>rhs.r;} }; node ns[nmax]; int main(){ int n=read(),T=read(); rep(i,1,n) ns[i].l=read(),ns[i].r=read(); sort(ns+1,ns+n+1); if(ns[1].l!=1){ printf("-1\n");return 0; } if(ns[1].r==T){ printf("1\n");return 0; }//没有特判这个然后就WA了。。。 int cur=1,t=ns[1].r,u,v,d,tmp,temp,ans=1; while(cur<=n){ u=-1;v=t; rep(i,cur+1,n) { if(ns[i].l>t+1) break; if(ns[i].r>v){ v=ns[i].r;u=i; } } if(u!=-1) ans++,cur=u,t=v; else break; if(t==T) { printf("%d\n",ans);return 0; } } printf("-1\n"); return 0; }
bzoj3399:贪心。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=25005; struct node{ int a[nmax],b[nmax]; }; node ns; int main(){ int n=read(),X=read(),Y=read(); rep(i,1,n) ns.a[i]=read(),ns.b[i]=read(); sort(ns.a+1,ns.a+n+1);sort(ns.b+1,ns.b+n+1); int ans=0; rep(i,1,n){ if(ns.a[i]>ns.b[i]) ans+=Y*(ns.a[i]-ns.b[i]); else ans+=X*(ns.b[i]-ns.a[i]); } printf("%d\n",ans); return 0; }
bzoj3398:递推!不要想复杂了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } int dp[100001]; int main(){ int n=read(),m=read(); dp[0]=1; rep(i,1,n) { if(i>m+1) dp[i]=dp[i-1]+dp[i-m-1];else dp[i]=dp[i-1]+1; if(dp[i]>=5000011) dp[i]-=5000011; } printf("%d\n",dp[n]); return 0; }
bzoj3396:直接最大流。。。
#include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=60; const int maxn=1605; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge es[maxn],*pt=es,*head[nmax],*cur[nmax],*p[nmax]; int cnt[nmax],h[nmax],id[nmax]; void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->cap=0;pt->next=head[v];head[v]=pt++; head[u]->rev=head[v];head[v]->rev=head[u]; } int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]+1==h[x]) break; if(e){ a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a,a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) cur[x]=e,h[x]=h[e->to]+1; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int main(){ int n=0,m=read(),u,v,d,tmp,temp,t,s; char S[5],T[5]; rep(i,1,m){ scanf("%s%s",S,T);d=read(); if(S[0]<='Z'&&S[0]>='A') { tmp=S[0]-'A'+26+1;u=id[tmp]; if(!u) id[tmp]=u=++n; if(S[0]=='A') s=u; if(S[0]=='Z') t=u; }else { tmp=S[0]-'a'+1;u=id[tmp]; if(!u) id[tmp]=u=++n; } if(T[0]<='Z'&&T[0]>='A') { tmp=T[0]-'A'+26+1;v=id[tmp]; if(!v) id[tmp]=v=++n; if(T[0]=='A') s=v; if(T[0]=='Z') t=v; }else { tmp=T[0]-'a'+1;v=id[tmp]; if(!v) id[tmp]=v=++n; } add(u,v,d); } printf("%d\n",maxflow(s,t,n)); return 0; }
bzoj3391:树形dp。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; int size[nmax],son[nmax],n; struct edge{ int to;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } void maxs(int &x,int y){ if(x<y) x=y; } void dfs(int x,int fa){ son[x]=1; qwq(x) if(o->to!=fa){ dfs(o->to,x); son[x]+=son[o->to]; maxs(size[x],son[o->to]); } maxs(size[x],n-son[x]); } int main(){ n=read();int u,v; rep(i,1,n-1) u=read(),v=read(),add(u,v); dfs(1,0); int tmp=n/2,flag=1; rep(i,1,n) if(size[i]<=tmp) flag=true,printf("%d\n",i); if(!flag) printf("NONE\n"); return 0; }
bzoj3390:最大生成树QAQ
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=20005; struct edge{ int s,t,d; bool operator<(const edge &rhs) const{ return d>rhs.d;} }; edge es[maxn]; int fa[nmax]; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } int main(){ int n=read(),m=read(),u,v,d; rep(i,1,m) { edge &o=es[i]; o.s=read(),o.t=read(),o.d=read(); } sort(es+1,es+m+1); rep(i,1,n) fa[i]=i; int ta,tb,cnt=0,ans=0; rep(i,1,m){ edge &o=es[i]; ta=find(o.s);tb=find(o.t); if(ta!=tb) { fa[ta]=tb; ans+=o.d; if(++cnt==n-1) break; } } if(cnt!=n-1) printf("-1\n"); else printf("%d\n",ans); return 0; }
❤bzoj3315:dp+优化。利用特点减少掉一维!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; struct node{ int x,w; bool operator<(const node&rhs)const{ return x<rhs.x;} }; node ns[nmax]; int dp[nmax][nmax],pre[nmax][nmax]; int as(int x){ return x<0?-x:x; } int main(){ int n=read(); rep(i,1,n) ns[i].x=read(),ns[i].w=read(); sort(ns+1,ns+n+1); /*dp[1][1]=ns[1].w; int ans=0; rep(i,2,n) { dp[i][i]=ns[i].w; rep(j,1,i-1) { rep(k,1,j) if(ns[i].x-ns[j].x>=ns[j].x-ns[k].x) dp[i][j]=max(dp[i][j],dp[j][k]); ans=max(ans,dp[i][j]+=ns[i].w); } } reverse(ns+1,ns+n+1); clr(dp,0);dp[1][1]=ns[1].w; rep(i,2,n) { dp[i][i]=ns[i].w; rep(j,1,i-1) { rep(k,1,j) if(as(ns[i].x-ns[j].x)>=as(ns[j].x-ns[k].x)) dp[i][j]=max(dp[i][j],dp[j][k]); ans=max(ans,dp[i][j]+=ns[i].w); } } printf("%d\n",ans); return 0;*/ dp[1][1]=pre[1][1]=ns[1].w; int ans=0,p; rep(i,2,n){ pre[i][i]=dp[i][i]=ns[i].w;p=i-1; dwn(j,i-1,1){ while(p&&as(ns[i].x-ns[j].x)>=as(ns[j].x-ns[p].x)||p>j) p--;p++; dp[i][j]=pre[p][j]+ns[i].w; ans=max(ans,dp[i][j]); pre[j][i]=max(dp[i][j],pre[j+1][i]); } } reverse(ns+1,ns+n+1); clr(dp,0);clr(pre,0); dp[1][1]=pre[1][1]=ns[1].w; rep(i,2,n){ pre[i][i]=dp[i][i]=ns[i].w;p=i-1; dwn(j,i-1,1){ while(p&&as(ns[i].x-ns[j].x)>=as(ns[j].x-ns[p].x)||p>j) p--;p++; dp[i][j]=pre[p][j]+ns[i].w; ans=max(ans,dp[i][j]); pre[j][i]=max(dp[i][j],pre[j+1][i]); } } printf("%d\n",ans); return 0; }
❤bzoj3314:单调队列就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; struct node{ int x,h; bool operator<(const node&rhs)const{ return x<rhs.x;} }; node ns[nmax]; bool fa[nmax],fb[nmax]; int q[nmax]; int main(){ int n=read(),D=read(); rep(i,1,n) ns[i].x=read(),ns[i].h=read(); sort(ns+1,ns+n+1); //rep(i,1,n) printf("%d %d\n",ns[i].x,ns[i].h); int l=1,r=0; rep(i,1,n){ while(l<=r&&ns[q[r]].h<ns[i].h) r--; q[++r]=i; while(l<=r&&ns[q[l]].x<ns[i].x-D) l++; if(ns[q[l]].h>=ns[i].h*2) fa[i]=1; //rep(j,l,r) printf("%d ",q[j]);printf("\n"); } l=1,r=0; int ans=0; dwn(i,n,1){ while(l<=r&&ns[q[r]].h<ns[i].h) r--; q[++r]=i; while(l<=r&&ns[q[l]].x>ns[i].x+D) l++; if(ns[q[l]].h>=ns[i].h*2) fb[i]=1; if(fa[i]&&fb[i]) ans++; //rep(j,l,r) printf("%d ",q[j]);printf("\n"); } printf("%d\n",ans); return 0; }
bzoj3301:康托展开两种情况。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long ll read(){ ll x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=25; ll a[nmax],ans[nmax];bool vis[nmax]; char s[5]; int main(){ ll n=read(),m=read(),u,v,d,tmp,temp; a[0]=1; rep(i,1,n) a[i]=a[i-1]*i; while(m--){ scanf("%s",s); if(s[0]=='P'){ clr(vis,0); u=read()-1; rep(i,1,n){ v=u/a[n-i]+1;d=0; rep(j,1,n){ if(!vis[j]) d++; if(d==v) { ans[i]=j;vis[j]=1; break; } } u%=a[n-i]; } rep(i,1,n-1) printf("%lld ",ans[i]);printf("%lld\n",ans[n]); }else{ clr(vis,0); rep(i,1,n) ans[i]=read(); u=1; rep(i,1,n){ vis[ans[i]]=1;v=0; rep(j,1,ans[i]-1) if(!vis[j]) v++; u+=v*a[n-i]; } printf("%lld\n",u); } } return 0; }
bzoj3300:可以先预处理出每个括号各自的配对然后递归就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const ll mod=12345678910; int match[nmax],s[nmax]; ll dfs(int l,int r){ if(r==l+1) return 1; if(match[l]==r) return (dfs(l+1,r-1)*2)%mod; return (dfs(l,match[l])+dfs(match[l]+1,r))%mod; } int main(){ int n=read(),u,v,d,tmp=0,temp=0; rep(i,1,n){ u=read(); if(!u) s[++tmp]=i; else match[s[tmp--]]=i; } printf("%lld\n",dfs(1,n)); return 0; }
❤bzoj3297:string+dp。。。stl神器。。。
#include<cstdio> #include<string> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) const int nmax=1005; int len[nmax]; char s[nmax]; string ch[nmax],dp[nmax]; bool pd(int u,int x){ rep(i,0,len[x]-1) if(s[u+i]!='?'&&s[u+i]!=ch[x][i]) return 0; return 1; } int main(){ int n,m,u,v,d,tmp,temp; scanf("%d%d",&n,&m); scanf("%s",s+1); rep(i,1,m) cin>>ch[i],len[i]=ch[i].size(); rep(i,1,n) rep(j,1,m){ u=i-len[j]; if(u<0) continue; if(u&&dp[u]=="") continue; if(pd(u+1,j)) if(dp[i]==""||dp[i]>dp[u]+ch[j]) dp[i]=dp[u]+ch[j]; } cout<<dp[n]<<endl; return 0; }
bzoj3296:并查集。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; const int maxn=30005; int fa[nmax+maxn]; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } int main(){ int n=read(),m=read(),u,v,ta,tb; rep(i,1,n+m) fa[i]=i; rep(i,1,n){ u=read(); rep(j,1,u) { v=read(); ta=find(i);tb=find(n+v); if(ta!=tb) fa[ta]=tb; } } int ans=0; rep(i,1,n) find(i); sort(fa+1,fa+n+1); rep(i,1,n) if(fa[i]!=fa[i-1]) ans++; printf("%d\n",ans-1); return 0; }
bzoj1681:最短路。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=505; const int maxn=2005; const int inf=0x7f7f7f7f; struct edge{ int to,dist;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++; } struct node{ int x,dist; node(int to,int dist):x(to),dist(dist){}; bool operator<(const node&rhs)const{ return dist>rhs.dist;} }; priority_queue<node>q; int dist[nmax],N,M,C,nd,tmp[nmax]; void dijkstra(){ clr(dist,0x7f);dist[1]=0; q.push(node(1,0)); int tx,td; while(!q.empty()){ node o=q.top();q.pop(); tx=o.x,td=o.dist; if(dist[tx]!=td) continue; qwq(tx) if(dist[o->to]>td+o->dist) dist[o->to]=td+o->dist,q.push(node(o->to,dist[o->to])); } } int main(){ N=read(),M=read(),C=read(),nd=read(); int u,v,d; rep(i,1,M) u=read(),v=read(),d=read(),add(u,v,d); dijkstra(); int ans=0; rep(i,1,C){ u=read(); if(dist[u]<=nd) ans++,tmp[ans]=i; } printf("%d\n",ans); rep(i,1,ans) printf("%d\n",tmp[i]); return 0; }
bzoj1668:递推。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) const int nmax=105; int map[nmax][nmax],dp[nmax][nmax]; int main(){ int n,m;scanf("%d%d",&n,&m); rep(i,1,n) rep(j,1,m) scanf("%d",&map[i][j]); dp[1][1]=map[1][1]; rep(i,2,m) rep(j,1,i) dp[j][i]=map[j][i]+max(dp[j][i-1],max(dp[j-1][i-1],dp[j+1][i-1])); printf("%d\n",dp[n][m]); return 0; }
bzoj1590:trie然后顺便维护一下子树末节点的个数就好了
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=500005; int ch[nmax][2],size[nmax],F[nmax]; int main(){ int N=read(),M=read(),u,v,pt=0,t; rep(i,1,N){ t=0;u=read(); rep(j,1,u) { v=read(); if(!ch[t][v]) ch[t][v]=++pt; t=ch[t][v];size[t]++; } F[t]++;//没有考虑重串WA了。 } //rep(i,1,pt) printf("%d ",size[i]); rep(i,1,M){ t=0;u=read();int ans=0; bool f=true; rep(j,1,u){ v=read(); if(!f) continue; if(ch[t][v]) ans+=F[ch[t][v]],t=ch[t][v]; else f=false; } if(f) ans+=size[ch[t][0]]+size[ch[t][1]]; printf("%d\n",ans); } return 0; }
❤bzoj1597:dp+斜率优化。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long ll read(){ ll x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; const ll inf=1e18; ll dp[nmax]; struct node{ ll x,y; bool operator<(const node&rhs)const { return x>rhs.x||x==rhs.x&&y>rhs.y;} }; node nodes[nmax]; ll x[nmax],y[nmax],q[nmax]; int main(){ int N=read(),u,v; rep(i,1,N) nodes[i].x=read(),nodes[i].y=read(); sort(nodes+1,nodes+N+1); int cnt=0; rep(i,1,N) if(nodes[i].y>y[cnt]) { x[++cnt]=nodes[i].x;y[cnt]=nodes[i].y; } int l=1,r=1; rep(i,1,cnt){ while(l<r&&y[i]*(x[q[l]+1]-x[q[l+1]+1])>dp[q[l+1]]-dp[q[l]]) l++; dp[i]=dp[q[l]]+x[q[l]+1]*y[i]; while(l<r&&(dp[q[r]]-dp[q[r-1]])*(x[q[r]+1]-x[i+1])>(dp[i]-dp[q[r]])*(x[q[r-1]+1]-x[q[r]+1])) r--; q[++r]=i; } printf("%lld\n",dp[cnt]); return 0; } /* 5 100 1 15 15 15 13 20 5 1 100 */
❤bzoj1690:分数规划!!!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=5005; const int inf=0x7f7f7f7f; struct edge{ int to,dist; double w;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; int a[nmax],tot[nmax],N,M; double d[nmax]; bool inq[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; } queue<int>q; bool spfa(){ rep(i,1,N) d[i]=0,inq[i]=1,q.push(i),tot[i]=1; while(!q.empty()){ int x=q.front();q.pop();inq[x]=0; qwq(x) if(d[o->to]>d[x]+o->w){ d[o->to]=d[x]+o->w; if(++tot[o->to]>=N) return 1; if(!inq[o->to]) q.push(o->to),inq[o->to]=1; } } return 0; } bool check(double L){ rep(i,1,N) qwq(i) o->w=L*o->dist-a[o->to]; return spfa(); } int main(){ N=read(),M=read();int u,v,d; rep(i,1,N) a[i]=read(); rep(i,1,M) u=read(),v=read(),d=read(),add(u,v,d); double l=0,r=10000,mid; while(r-l>0.001){ mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; } printf("%.2lf\n",l); return 0; }
bzoj1666:模拟。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int main(){ int n,ans=0;scanf("%d",&n); while(n!=1){ ans++; if(n%2==0) n>>=1; else n=n*3+1; } printf("%d\n",ans); return 0; }
bzoj1593:线段树经典
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define lson l,mid,x<<1 #define rson mid+1,r,x<<1|1 int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; int lmax[nmax<<2],rmax[nmax<<2],omax[nmax<<2],col[nmax<<2]; void pushup(int x,int cnt){ lmax[x]=((lmax[x<<1]==(cnt-(cnt>>1)))?lmax[x<<1]+lmax[x<<1|1]:lmax[x<<1]); rmax[x]=((rmax[x<<1|1]==(cnt>>1)?rmax[x<<1|1]+rmax[x<<1]:rmax[x<<1|1])); omax[x]=max(rmax[x<<1]+lmax[x<<1|1],max(omax[x<<1],omax[x<<1|1])); } void build(int l,int r,int x){ col[x]=-1;lmax[x]=rmax[x]=omax[x]=r-l+1; if(l==r) return ; int mid=(l+r)>>1; build(lson);build(rson); } void pushdown(int x,int cnt){ if(col[x]!=-1) { col[x<<1]=col[x<<1|1]=col[x]; lmax[x<<1]=rmax[x<<1]=omax[x<<1]=col[x]?0:cnt-(cnt>>1); lmax[x<<1|1]=rmax[x<<1|1]=omax[x<<1|1]=col[x]?0:(cnt>>1); col[x]=-1;} } void update(int tl,int tr,int p,int l,int r,int x){ if(tl<=l&&tr>=r){ if(p) col[x]=p,lmax[x]=rmax[x]=omax[x]=0; else col[x]=p,lmax[x]=rmax[x]=omax[x]=r-l+1; }else{ pushdown(x,r-l+1); int mid=(l+r)>>1; if(tl<=mid) update(tl,tr,p,lson); if(tr>mid) update(tl,tr,p,rson); pushup(x,r-l+1); } } int query(int cnt,int l,int r,int x){ if(l==r) return l; pushdown(x,r-l+1); int mid=(l+r)>>1; if(omax[x<<1]>=cnt) return query(cnt,lson); if(rmax[x<<1]+lmax[x<<1|1]>=cnt) return mid-rmax[x<<1]+1; return query(cnt,rson); } int main(){ int N=read(),M=read(),u,v,d; build(1,N,1); rep(i,1,M){ u=read(),v=read(); if(u==1){ if(omax[1]<v) printf("0\n"); else{ d=query(v,1,N,1);printf("%d\n",d); update(d,d+v-1,1,1,N,1); } }else{ d=read(); update(v,v+d-1,0,1,N,1); } } return 0; }
bzoj1592:花最少的代价把序列转换成不下降或不上升队列。dp+优化还是利用特点减掉了一维。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=2005; const int inf=0x7f7f7f7f; int a[nmax],b[nmax]; int as(int x){ return x<0?-x:x; } int f[nmax][nmax],g[nmax][nmax]; int main(){ int n=read(),u,v; rep(i,1,n) b[i]=a[i]=read(); sort(a+1,a+n+1); rep(i,1,n) rep(j,1,n){ f[i][j]=g[i-1][j]+as(b[i]-a[j]); if(j==1) g[i][j]=f[i][j]; else g[i][j]=min(f[i][j],g[i][j-1]); } int ans=g[n][n]; clr(g,0);clr(f,0); reverse(b+1,b+n+1); rep(i,1,n) rep(j,1,n){ f[i][j]=g[i-1][j]+as(b[i]-a[j]); if(j==1) g[i][j]=f[i][j]; else g[i][j]=min(f[i][j],g[i][j-1]); } printf("%d\n",min(g[n][n],ans)); return 0; }
bzoj1596:树形dp/贪心的做法。。。辛辛苦苦写了那么长的dp结果那么短的贪心同样A了。。。
/*#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; const int maxn=20005; const int inf=0x7f7f7f7f; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; int dp[nmax][3]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } void dfs(int x,int fa){ dp[x][1]=1;dp[x][0]=inf;dp[x][2]=0; int sum=0,flag=false,tmp=inf; qwq(x) if(o->to!=fa){ int to=o->to;dfs(to,x); dp[x][1]+=min(dp[to][0],min(dp[to][1],dp[to][2])); dp[x][2]+=min(dp[to][0],dp[to][1]); sum+=min(dp[to][1],dp[to][0]); if(dp[to][1]<dp[to][0]) flag=true; else tmp=min(tmp,dp[to][1]-dp[to][0]); } if(sum){ if(!flag) sum+=tmp; dp[x][0]=sum; } } int main(){ int N=read(),u,v; rep(i,1,N-1) u=read(),v=read(),add(u,v); dfs(1,0); printf("%d\n",min(dp[1][1],dp[1][0])); return 0; }*/ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; const int maxn=20005; const int inf=0x7f7f7f7f; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; bool vis[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; pt->to=u;pt->next=head[v];head[v]=pt++; } int ans=0; void dfs(int x,int fa){ bool flag=false; qwq(x) if(o->to!=fa){ dfs(o->to,x); if(vis[o->to]) flag=true; } if(!flag&&!vis[x]&&!vis[fa]) vis[fa]=1,ans++; } int main(){ int N=read(),u,v; rep(i,1,N-1) u=read(),v=read(),add(u,v); dfs(1,0); printf("%d\n",ans); return 0; }
bzoj1652:跟1742相似,,都是套路啊
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=2005; int a[nmax],f[nmax][nmax]; int main(){ int n;scanf("%d",&n); rep(i,1,n) scanf("%d",&a[i]); rep(i,1,n) { for(int j=1;j+i-1<=n;j++){ f[j][j+i-1]=max(f[j+1][j+i-1]+(n-i+1)*a[j],f[j][j+i-2]+(n-i+1)*a[j+i-1]); } } printf("%d\n",f[1][n]); return 0; }
bzoj1684:模拟这
#include<cstdio> double as(double x){ return x<0?-x:x; } int main(){ int N,D; scanf("%d%d",&N,&D); double ans=2.0,tmp=N*1.0/D; int ta,tb,temp; for(int i=1;i<=32767;i++){ temp=tmp*i; if(as(tmp-temp*1.0/i)<ans&&i*N!=D*temp) ans=as(tmp-temp*1.0/i),ta=temp,tb=i; if(as(tmp-(temp+1)*1.0/i)<ans&&i*N!=D*(temp+1)) ans=as(tmp-(temp+1)*1.0/i),ta=temp+1,tb=i; } printf("%d %d\n",ta,tb); return 0; }
❤bzoj3892:dp。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0,f=1;char c=getchar(); while(!isdigit(c)){ if(c=='-') f=-1;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } const int nmax=505; const int inf=0x7f7f7f7f; int dp[nmax][nmax],x[nmax],y[nmax]; int as(int x){ return x<0?-x:x; } int main(){ int N=read(),K=read(); rep(i,1,N) x[i]=read(),y[i]=read(); clr(dp,0x7f);dp[1][0]=0; rep(i,2,N) { for(int j=0;j<=i-2&&j<=K;j++){ rep(k,0,j) dp[i][j]=min(dp[i][j],dp[i-k-1][j-k]+as(x[i]-x[i-k-1])+as(y[i]-y[i-k-1])); } } printf("%d\n",dp[N][min(K,N-2)]); }