bzoj 1606: [Usaco2008 Dec]Hay For Sale 购买干草——背包
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int h,n,f[50007],k; int main() { h=read(); n=read(); f[0]=1; for(int i=1;i<=n;i++){ k=read(); for(int j=h;j>=k;j--) if(f[j-k]) f[j]=1; } for(int i=h;i>=0;i--)if(f[i]){printf("%d ",i); break;} return 0; }
bzoj 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头——筛数
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,f[1000007],v[100007],ans[1000007]; int main() { n=read(); for(int i=1;i<=n;i++) v[i]=read(),f[v[i]]++; for(int i=1;i<=(int)1e6;i++)if(f[i]){ for(int j=i;j<=(int)1e6;j+=i) if(f[j]) ans[j]+=f[i]; } for(int i=1;i<=n;i++) printf("%d ",ans[v[i]]-1); return 0; }
bzoj 1597: [Usaco2008 Mar]土地购买——斜率优化dp
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=50007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL x[M],y[M],f[M]; int q[M],n,tot; struct node{LL x,y;}a[M]; bool cmp(node a,node b){return a.x!=b.x?a.x<b.x:a.y<b.y;} double slop(int a,int b){return (double)(f[b]-f[a])/(y[a+1]-y[b+1]);} int main() { n=read(); for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++){ while(tot&&y[tot]<=a[i].y) tot--; x[++tot]=a[i].x; y[tot]=a[i].y; } int head=0,tail=0; for(int i=1;i<=tot;i++){ while(head<tail&&slop(q[head],q[head+1])<x[i]) head++; int v=q[head]; f[i]=f[v]+y[v+1]*x[i]; while(head<tail&&slop(q[tail-1],q[tail])>slop(q[tail],i)) tail--; q[++tail]=i; } printf("%lld ",f[tot]); return 0; }
bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队 ——zkw版
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1<<19,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,q,l,r; int mx[N<<1],mn[N<<1]; int push_ans(int l,int r){ int mx1=0,mn1=inf; for(l+=N-1,r+=N+1;r-l!=1;l>>=1,r>>=1){ if(~l&1) mx1=max(mx1,mx[l^1]),mn1=min(mn1,mn[l^1]); if(r&1) mx1=max(mx1,mx[r^1]),mn1=min(mn1,mn[r^1]); } return mx1-mn1; } int main() { n=read(); q=read(); for(int i=1;i<=n;i++) mx[N+i]=mn[N+i]=read(); for(int i=N-1;i;i--) mx[i]=max(mx[i<<1],mx[i<<1^1]),mn[i]=min(mn[i<<1],mn[i<<1^1]); for(int i=1;i<=q;i++){ l=read(); r=read(); printf("%d ",push_ans(l,r)); } return 0; }
bzoj 1602: [Usaco2008 Oct]牧场行走——lca
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int vis[M],d[M],q[M]; int n,k,first[M],cnt; struct node{int to,w,next;}e[2*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,w,first[a]}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} void push_ans(int k){ int head=0,tail=1; q[0]=k; vis[k]=1; while(head!=tail){ int x=q[head++]; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!vis[now]){ vis[now]=1; d[now]=d[x]+e[i].w; q[tail++]=now; } } } } int main() { int x,y,w; n=read(); k=read(); for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w); for(int i=1;i<=k;i++){ x=read(); y=read(); memset(vis,0,sizeof(vis)); memset(d,0,sizeof(d)); push_ans(x); printf("%d ",d[y]); } return 0; }
bzoj 1610: [Usaco2008 Feb]Line连线游戏——几何
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int M=257; bool pd(double x,double y){return fabs(x-y)<1e-7;} int n,cnt,ans; double x[M],y[M],a[M*M]; bool cmp(double x,double y){return x<y;} int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(!pd(x[i],x[j])) a[++cnt]=(y[i]-y[j])/(x[i]-x[j]); else ans=1; } sort(a+1,a+1+cnt,cmp); if(cnt>=1) ans++; for(int i=2;i<=cnt;i++) if(!pd(a[i],a[i-1])) ans++; printf("%d ",ans); return 0; }
bzoj 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 ——dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=350007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,c[M],f[M][4],ans=inf; int main() { n=read(); for(int i=1;i<=n;i++) c[i]=read(); memset(f,0x3f,sizeof(f)); f[0][1]=f[0][2]=f[0][3]=0; for(int k=1;k<=n;k++) for(int i=1;i<=3;i++){ for(int j=1;j<=i;j++) f[k][i]=min(f[k][i],f[k-1][j]); if(i!=c[k]) f[k][i]++; } for(int i=1;i<=3;i++) ans=min(ans,f[n][i]); memset(f,0x3f,sizeof(f)); f[n+1][1]=f[n+1][2]=f[n+1][3]=0; for(int k=n;k>=1;k--) for(int i=1;i<=3;i++){ for(int j=1;j<=i;j++) f[k][i]=min(f[k][i],f[k+1][j]); if(i!=c[k]) f[k][i]++; } for(int i=1;i<=3;i++) ans=min(ans,f[1][i]); printf("%d ",ans); return 0; }
bzoj 1625: [Usaco2007 Dec]宝石手镯——01背包
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=3507,N=15007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,c[M],w[M],f[N]; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) c[i]=read(),w[i]=read(); for(int i=1;i<=n;i++) for(int j=m;j>=c[i];j--) f[j]=max(f[j],f[j-c[i]]+w[i]); printf("%d ",f[m]); return 0; }
bzoj 1617: [Usaco2008 Mar]River Crossing渡河问题——简单dp
#include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; const int M=5507,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,f[M],w[M],s[M]; int main() { n=read(); s[0]=read(); for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n;i++) s[i]=s[i-1]+w[i]; for(int i=1;i<=n;i++){ f[i]=inf; for(int j=1;j<=i;j++) f[i]=min(f[i],f[i-j]+s[j]+s[0]); } printf("%d ",f[n]-s[0]); return 0; }
bzoj 1650: [Usaco2006 Dec]River Hopscotch 跳石子——二分
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=55007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int L,n,m,s[M]; bool check(int mx){ int cnt=0,sum=0; for(int i=1;i<=n;i++){ if(s[i]-sum<=mx) cnt++; else sum=s[i]; } return cnt<=m; } int main() { L=read(); n=read(); m=read(); for(int i=1;i<=n;i++) s[i]=read(); s[++n]=L; sort(s+1,s+1+n); int l=0,r=L+1; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid-1; }printf("%d ",l); return 0; }
bzoj 2718: [Violet 4]毕业旅行——二分图匹配+最大反链
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=557,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,n,m,S,T,f[M][M]; int vis[M],d[M],first[M],cur[M],cnt=1; struct node{int to,next,flow;}e[M*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}; void insert(int a,int b){ins(a,b,1); ins(b,a,0);} void floyd(){ for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]|=f[i][k]&f[k][j]; for(int i=1;i<=n;i++) f[i][i]=0; } queue<int>q; int bfs(){ memset(d,-1,sizeof(d)); q.push(S); d[S]=0; while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||a==0) return a; int f,flow=0; for(int& i=cur[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } int main() { int x,y; n=read(); m=read(); ans=n; S=0; T=2*n+1; for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1; floyd(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(f[i][j]) insert(i,j+n); for(int i=1;i<=n;i++) insert(S,i),insert(i+n,T); while(bfs()){ for(int i=S;i<=T;i++) cur[i]=first[i]; ans-=dfs(S,inf); }printf("%d ",ans); return 0; }
bzoj 1613: [Usaco2007 Jan]Running贝茜的晨练计划——dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,w[M]; int f[M][1007]; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) f[i][j]=f[i-1][j-1]+w[i]; f[i][0]=f[i-1][0]; for(int j=1;j<=m;j++) if(i>j) f[i][0]=max(f[i][0],f[i-j][j]); } printf("%d ",f[n][0]); return 0; }
bzoj 1230: [Usaco2008 Nov]lites 开关灯——线段树
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1<<18; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m; int k,L,R; struct node{ node *lc,*rc; int l,r,mid,sum,h,sz; void pr(){sum=sz-sum; h^=1;} void up(){sum=lc->sum+rc->sum;} void down(){h=0; lc->pr(); rc->pr();} void modify(){ if(L<=l&&r<=R) return pr(); if(h) down(); if(L<=mid) lc->modify(); if(R>mid) rc->modify(); up(); } int query(){ if(L<=l&&r<=R) return sum; if(h) down(); int tot=0; if(L<=mid) tot+=lc->query(); if(R>mid) tot+=rc->query(); return tot; } node*build(int L,int R); }tr[M],*np=tr+1; node*node::build(int L,int R){ l=L; r=R; sz=R-L+1; if(L<R){ mid=(L+R)>>1; lc=++np; lc->build(L,mid); rc=++np; rc->build(mid+1,R); } } int main(){ n=read(); m=read(); tr[1].build(1,n); for(int i=1;i<=m;i++){ k=read(); L=read(); R=read(); if(!k) tr[1].modify(); else if(k) printf("%d ",tr[1].query()); } return 0; }
bzoj1600 1600: [Usaco2008 Oct]建造栅栏——简单dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n; int f[15][2507]; int main() { n=read(); f[0][0]=1; int mx=(n+1)/2-1; for(int k=1;k<=4;k++) for(int i=1;i<=n;i++) for(int j=1;j<=min(i,mx);j++) f[k][i]+=f[k-1][i-j]; printf("%d ",f[4][n]); return 0; }
bzoj 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
n^3算法 用的bitset可能快点n^3/32吧 暂时没有更优的方法
#include<cstdio> #include<bitset> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m; bitset<107> f[107]; int main(){ int x,y; n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1; for(int k=1;k<=n;++k) for(int i=1;i<=n;i++) if(f[i][k]) f[i]|=f[k]; int res=0; for(int i=1;i<=n;++i){ int sum=1; for(int j=1;j<=n;j++) sum+=f[i][j]|f[j][i]; if(sum==n) ++res; } printf("%d",res); return 0; }
好的还有nm/32的写法 但是实测没快多少
#include<cstdio> #include<bitset> #include<cstring> #include<algorithm> #include<queue> #include<iostream> using namespace std; const int M=107; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,ans; bitset<107>f[107]; int first[M],cnt,in[M],vis[M],map[M][M]; queue<int>q; int main(){ int x,y; n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),map[y][x]=1,in[x]++; for(int i=1;i<=n;i++){ f[i][i]=1; if(!in[i]) q.push(i),vis[i]=1; } while(!q.empty()){ int x=q.front(); q.pop(); for(int i=1;i<=n;i++)if(map[x][i]&&!vis[i]){ in[i]--; f[i]|=f[x]; if(!in[i]) vis[i]=1,q.push(i); } } int ans=0; for(int i=1;i<=n;i++){ int sum=0; for(int j=1;j<=n;j++) sum+=f[i][j]|f[j][i]; if(sum==n) ans++; } printf("%d ",ans); return 0; }
bzoj1614: [Usaco2007 Jan]Telephone Lines架设电话线——二分答案
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=2e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,mx; int first[M],cnt,d[M],vis[M]; struct node{int to,next,w;}e[10*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} queue<int>q; int spfa(int mx){ memset(vis,0,sizeof(d)); memset(d,0x3f,sizeof(d)); q.push(1); d[1]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to,v=d[x]+(e[i].w>mx); if(d[now]>v){ d[now]=v; if(!vis[now]) vis[now]=1,q.push(now); } } } return d[n]<=k; } int main() { int x,y,w; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w),mx=max(mx,w); int ans=-1,l=0,r=mx; while(l<=r){ int mid=(l+r)>>1; if(spfa(mid)) ans=mid,r=mid-1; else l=mid+1; }printf("%d ",ans); return 0; }
bzoj 1603. -- [Usaco2008 Oct]打谷机——简单模拟
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=1e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,cnt,d[M]; struct node{int x,y,c;}e[M]; bool cmp(node a,node b){return a.x<b.x;} int main() { n=read(); for(int i=1;i<n;i++) e[i].x=read(),e[i].y=read(),e[i].c=read(); sort(e+1,e+n,cmp); d[1]=0; for(int i=1;i<n;i++) if(e[i].c==0) d[e[i].y]=d[e[i].x]; else d[e[i].y]=1-d[e[i].x]; printf("%d ",d[n]); return 0; }
bzoj 1599: [Usaco2008 Oct]笨重的石子
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int s[4],mx,ans; int f[107],sum; int main() { for(int i=1;i<=3;i++) s[i]=read(),sum+=s[i]; for(int s1=1;s1<=s[1];s1++) for(int s2=1;s2<=s[2];s2++) for(int s3=1;s3<=s[3];s3++) f[s1+s2+s3]++; for(int i=1;i<=sum;i++) if(f[i]>mx) mx=f[i],ans=i; printf("%d ",ans); return 0; }
bzoj 1692: [Usaco2007 Dec]队列变换——后缀数组
暂时不会写 留坑代填 填在后面了233(没用后缀数组QAQ)
bzoj 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛——简单dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=107; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,T; int sx,sy,ex,ey; int f[M][M][25],map[M][M]; int xi[5]={0,0,1,0,-1},yi[5]={0,1,0,-1,0}; char s[155]; int main() { n=read(); m=read(); T=read(); for(int i=1;i<=n;i++){ scanf("%s",s+1); for(int j=1;j<=m;j++) if(s[j]=='.') map[i][j]=1; } sx=read(); sy=read(); ex=read(); ey=read(); f[sx][sy][0]=1; for(int k=1;k<=T;k++) for(int x=1;x<=n;x++) for(int y=1;y<=m;y++)if(map[x][y]) for(int i=1;i<=4;i++){ int nx=x+xi[i],ny=y+yi[i]; if(nx<1||nx>n||ny<1||ny>m||!map[nx][ny]||!f[nx][ny][k-1]) continue; f[x][y][k]+=f[nx][ny][k-1]; } printf("%d ",f[ex][ey][T]); return 0; }
bzoj1666 : [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏——模拟
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=107; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,ans; int main() { n=read(); while(n!=1){ ans++; if(n%2) n=n*3+1; else n/=2; }printf("%d ",ans); return 0; }
bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路——最小生成树
1. Kruskal 这个写法超级慢QAQ 直接n^2logn^2 暴力
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int M=1e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,f[M],map[M][M]; int find(int x){return f[x]==x?x:f[x]=find(f[x]);} double x[M],y[M],ans; double calc(int p,int q){return sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));} int cnt,sum; struct node{int from,to; double d;}e[M*M]; bool cmp(node a,node b){return (b.d-a.d)>1e-7;} int main() { int p,q; n=read(); m=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]); for(int i=1;i<=m;i++){ p=read(); q=read(); map[p][q]=map[q][p]=1; e[++cnt]=(node){p,q,calc(p,q)}; } sort(e+1,e+1+cnt,cmp); for(int i=1;i<=cnt;i++){ int p=find(e[i].from),q=find(e[i].to); if(p==q) continue; sum++; f[q]=p; } if(sum==n) return printf("%.2lf ",ans),0; cnt=0; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)if(!map[i][j]) e[++cnt]=(node){i,j,calc(i,j)}; sort(e+1,e+1+cnt,cmp); for(int i=1;i<=cnt;i++){ int p=find(e[i].from),q=find(e[i].to); if(p==q) continue; ans+=e[i].d; f[q]=p; sum++; if(sum==n) break; }printf("%.2lf ",ans); return 0; }
2. prim 快好多啊 稠密图n^2 比 kruskal 快好多啊QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int M=1e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,vis[M],f[M][M]; double x[M],y[M],ans,map[M][M],d[M]; double calc(int p,int q){return sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));} void prim(){ d[1]=0; vis[1]=1; for(int i=2;i<=n;i++) d[i]=map[1][i]; for(int i=2;i<=n;i++){ double mn=inf; int h=0; for(int j=2;j<=n;j++) if(!vis[j]&&mn>d[j]) mn=d[j],h=j; ans+=mn; d[h]=0; vis[h]=1; for(int j=2;j<=n;j++) if(!vis[j]&&map[h][j]<d[j]) d[j]=map[h][j]; } } int main() { int p,q; n=read(); m=read(); for(int i=1;i<=n;i++) scanf("%lf %lf",&x[i],&y[i]); for(int i=1;i<=m;i++){ p=read(); q=read(); f[p][q]=f[q][p]=1; } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)if(!f[i][j]) map[i][j]=map[j][i]=calc(i,j); prim(); printf("%.2lf ",ans); return 0; }
bzoj 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式
又一个代填的坑QAQ
这又是一道能用hash填的坑 我们可以二分答案 然后用hash套hash的方法写辣 复杂度nlongn
#include<cstdio> #include<cstring> #include<algorithm> #define LL unsigned long long const int M=45007,P=9875321,mod=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k; LL w[M],f[M]; int first[mod],cnt,ans[M]; struct node{LL v; int next;}e[M]; int find(LL x){ LL w=x%mod; for(int i=first[w];i;i=e[i].next)if(e[i].v==x) return i; e[++cnt]=(node){x,first[w]}; first[w]=cnt; return cnt; } bool check(int l){ cnt=0; memset(first,0,sizeof(first)); memset(ans,0,sizeof(ans)); for(int i=1;i<=n-l+1;i++){ LL ly=f[i+l-1]-f[i-1]*w[l]; int s=find(ly); ans[s]++; if(ans[s]>=k) return 1; } return 0; } int main(){ n=read(); k=read(); w[0]=1; for(int i=1;i<=n;i++) w[i]=w[i-1]*P; for(int i=1;i<=n;i++) f[i]=f[i-1]*P+read(); if(k==0) return printf("%d ",n),0; int l=0,r=n; while(l<r){ int mid=(l+r+1)>>1; if(check(mid)) l=mid; else r=mid-1; }printf("%d ",l); return 0; }
【bzoj1611】[Usaco2008 Feb]Meteor Shower流星雨-bfs
小心数组越界QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=55007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,xx[5]={0,0,1,0,-1},yy[5]={0,1,0,-1,0}; int map[307][307],vis[307][307]; struct node{int x,y,T;}; queue<node>q; int main() { for(int i=0;i<=305;i++) for(int j=0;j<=305;j++) map[i][j]=inf; int x,y,h; n=read(); for(int i=1;i<=n;i++){ x=read(); y=read(); h=read(); map[x][y]=min(map[x][y],h); for(int k=1;k<=4;k++){ int nx=x+xx[k],ny=y+yy[k]; if(nx<0||ny<0) continue;//小心数组越界 map[nx][ny]=min(map[nx][ny],h); } } if(!map[0][0]) return printf("-1 "),0; vis[0][0]=1; q.push((node){0,0,0}); while(!q.empty()){ node s=q.front(); q.pop(); if(map[s.x][s.y]==inf) return printf("%d ",s.T),0; for(int k=1;k<=4;k++){ int nx=s.x+xx[k],ny=s.y+yy[k],nowh=s.T+1; if(nx<0||ny<0||map[nx][ny]<=nowh||vis[nx][ny]) continue; vis[nx][ny]=1; q.push((node){nx,ny,nowh}); } }printf("-1 "); return 0; }
bzoj 1724: [Usaco2006 Nov]Fence Repair 切割木板
切割的逆过程就是合并 所以切割木板=合并果子
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,k,ans; struct node{ LL w; bool operator <(const node& x)const {return x.w<w;} }; priority_queue<node>q; int main() { n=read(); for(int i=1;i<=n;i++) k=read(),q.push((node){k}); for(int i=1;i<n;i++){ node x=q.top(); q.pop(); node y=q.top(); q.pop(); int h=x.w+y.w; ans+=h; q.push((node){h}); }printf("%lld ",ans); return 0; }
bzoj 1621: [Usaco2008 Open]Roads Around The Farm分岔路口——模拟
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,ans; queue<int>q; int main() { n=read(); k=read(); q.push(n); while(!q.empty()){ int x=q.front(); q.pop(); if(x>k&&(x-k)%2==0){ int now1=(x-k)/2,now2=now1+k; q.push(now1); q.push(now2); } else ans++; }printf("%d ",ans); return 0; }
bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛-二分求最长上升子序列
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=5007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,d,q[M],cnt; int find(int w){ int l=0,r=cnt; while(l<=r){ int mid=(l+r)>>1; if(q[mid]<w) l=mid+1; else r=mid-1; } return l; } int main() { n=read(); k=read(); q[++cnt]=k; for(int i=2;i<=n;i++){ k=read(); if(q[cnt]<k) q[++cnt]=k; else d=find(k),q[d]=k; }printf("%d ",cnt); return 0; }
bzoj 1232: [Usaco2008Nov]安慰奶牛cheer——最小生成树
每条边的权值就是他的两个端点的c+他的长度*2
当然要记得选一个权值最小的点当作跟
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=10007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans=inf,n,m,first[M],cnt,c[M],f[M]; int find(int x){return f[x]==x?x:f[x]=find(f[x]);} struct node{int from,to,w,next;}e[15*M]; bool cmp(node a,node b){return a.w<b.w;} void ins(int a,int b,int w){e[++cnt]=(node){a,b,w,first[a]}; first[a]=cnt;} int main() { int x,y,w; n=read(); m=read(); for(int i=1;i<=n;i++) c[i]=read(),f[i]=i,ans=min(ans,c[i]); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,(w<<1)+c[x]+c[y]); sort(e+1,e+1+cnt,cmp); int h=0; for(int i=1;i<=m;i++){ int p=find(e[i].from),q=find(e[i].to); if(p==q) continue; f[q]=p; ans+=e[i].w; h++; if(h==n-1) break; }printf("%d ",ans); }
bzoj 1636: [Usaco2007 Jan]Balanced Lineup-zkw线段树
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1<<19,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,q,l,r; int mx[N<<1],mn[N<<1]; int push_ans(int l,int r){ int mx1=0,mn1=inf; for(l+=N-1,r+=N+1;r-l!=1;l>>=1,r>>=1){ if(~l&1) mx1=max(mx1,mx[l^1]),mn1=min(mn1,mn[l^1]); if(r&1) mx1=max(mx1,mx[r^1]),mn1=min(mn1,mn[r^1]); } return mx1-mn1; } int main() { n=read(); q=read(); for(int i=1;i<=n;i++) mx[N+i]=mn[N+i]=read(); for(int i=N-1;i;i--) mx[i]=max(mx[i<<1],mx[i<<1^1]),mn[i]=min(mn[i<<1],mn[i<<1^1]); for(int i=1;i<=q;i++){ l=read(); r=read(); printf("%d ",push_ans(l,r)); } return 0; }
bzoj 1618: [Usaco2008 Nov]Buying Hay 购买干草——完全背包
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,h,mx,ans=inf; int f[55007]; int c[107],w[107]; int main() { n=read(); h=read(); for(int i=1;i<=n;i++) c[i]=read(),w[i]=read(),mx=max(mx,c[i]); memset(f,0x3f,sizeof(f)); f[0]=0; for(int i=1;i<=n;i++) for(int j=c[i];j<h+mx;j++) f[j]=min(f[j],f[j-c[i]]+w[i]); for(int i=0;i<mx;i++) ans=min(ans,f[h+i]); printf("%d ",ans); return 0; }
bzoj 1572: [Usaco2009 Open]工作安排Job——贪心+堆
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=100007; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,cnt,ans; struct pos{LL d,w;}e[M]; bool cmp(pos a,pos b){return a.d<b.d;} priority_queue<LL>q; int main() { n=read(); for(int i=1;i<=n;i++) e[i].d=read(),e[i].w=read(); sort(e+1,e+1+n,cmp); for(int i=1;i<=n;i++){ ans+=e[i].w; q.push(-e[i].w); cnt++; if(cnt>e[i].d) cnt--,ans+=q.top(),q.pop(); }printf("%lld ",ans); return 0; }
bzoj 1631: [Usaco2007 Feb]Cow Party——spfa
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1007,M=150007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k; int first[N],cnt,star[N],cntq; struct node{int to,next,w;}e[M],q[M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insq(int a,int b,int w){q[++cntq]=(node){b,star[a],w}; star[a]=cnt;} int d1[N],d2[N],vis[N]; queue<int>qu; void spfa1(){ memset(d1,0x3f,sizeof(d1)); d1[k]=0; vis[k]=1; qu.push(k); while(!qu.empty()){ int x=qu.front(); vis[x]=0; qu.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d1[now]>d1[x]+e[i].w){ d1[now]=d1[x]+e[i].w; if(!vis[now]) qu.push(now),vis[now]=1; } } } } void spfa2(){ memset(d2,0x3f,sizeof(d2)); d2[k]=0; vis[k]=1; qu.push(k); while(!qu.empty()){ int x=qu.front(); vis[x]=0; qu.pop(); for(int i=star[x];i;i=q[i].next){ int now=q[i].to; if(d2[now]>d2[x]+q[i].w){ d2[now]=d2[x]+q[i].w; if(!vis[now]) qu.push(now),vis[now]=1; } } } } int main() { int x,y,w; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,w),insq(y,x,w); spfa1(); spfa2(); int ans=0; for(int i=1;i<=n;i++) ans=max(ans,d1[i]+d2[i]); printf("%d ",ans); return 0; }
bzoj 1231: [Usaco2008 Nov]mixup2 混乱的奶牛——状压dp
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define LL long long using namespace std; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int s,n,mn; LL f[20][1<<16],h[25],w[25]; int main() { n=read(); mn=read(); s=(1<<n)-1; for(int i=1;i<=n;i++) h[i]=read(),w[i]=1<<(i-1),f[i][w[i]]=1; for(int k=1;k<=s;k++) for(int i=1;i<=n;i++)if(!(k&w[i])) for(int j=1;j<=n;j++)if((k&w[j])&&abs(h[i]-h[j])>mn) f[i][k|w[i]]+=f[j][k]; LL ans=0; for(int i=1;i<=n;i++) ans+=f[i][s]; printf("%lld ",ans); return 0; }
bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路——spfa求次短路
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=5007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m; int first[M],cnt; struct node{int to,next,w;}e[250007]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} int d1[M],d2[M],vis[M]; queue<int>q; void spfa(){ memset(d1,0x3f,sizeof(d1)); memset(d2,0x3f,sizeof(d2)); d1[1]=0; vis[1]=0; q.push(1); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ bool f=false; int now=e[i].to; if(d1[x]+e[i].w<d1[now]) f=true,d2[now]=min(d1[now],d2[x]+e[i].w),d1[now]=d1[x]+e[i].w; else if(d1[x]+e[i].w>d1[now]&&d1[x]+e[i].w<d2[now]) f=true,d2[now]=d1[x]+e[i].w; else if(d2[x]+e[i].w<d2[now]) f=true,d2[now]=d2[x]+e[i].w; if(f&&!vis[now]) vis[now]=1,q.push(now); } vis[x]=0; } } int main() { int x,y,w; n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w); spfa(); printf("%d ",d2[n]); return 0; }
bzoj 1677: [Usaco2005 Jan]Sumsets 求和——完全背包
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mod=1e9,M=1e6+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,f[M]; int main() { n=read(); f[0]=1; for(int i=0;(1<<i)<=n;i++){ int now=1<<i; for(int j=now;j<=n;j++) (f[j]+=f[j-now])%=mod; }printf("%d ",f[n]); return 0; }
bzoj 1657: [Usaco2006 Mar]Mooo 奶牛的歌声——单调栈
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=50007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,h[M],v[M]; int st[M],top,s[M],ans; int main() { n=read(); for(int i=1;i<=n;i++) h[i]=read(),v[i]=read(); for(int i=1;i<=n;i++){ while(top&&h[st[top]]<h[i]) s[i]+=v[st[top--]]; st[++top]=i; } top=0; for(int i=n;i;i--){ while(top&&h[st[top]]<h[i]) s[i]+=v[st[top--]]; st[++top]=i; } for(int i=1;i<=n;i++) ans=max(ans,s[i]); printf("%d ",ans); return 0; }
bzoj 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛——bfs
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int mx=100000; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int s,k,now,d[mx+7]; queue<int>q; int main() { s=read(); k=read(); q.push(s); d[s]=1; if(s>=k) return printf("%d ",s-k),0; while(!q.empty()){ int x=q.front(); q.pop(); now=x+1;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now); now=x-1;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now); now=2*x;if(now>=0&&now<=mx&&!d[now]) d[now]=d[x]+1,q.push(now); if(d[k]) return printf("%d ",d[k]-1),0; } return 0; }
bzoj 1660: [Usaco2006 Nov]Bad Hair Day 乱发节——单调栈
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int h[M],n; LL ans; int st[M],top; int main() { n=read(); for(int i=1;i<=n;i++) h[i]=read(); for(int i=1;i<=n;i++){ while(top&&h[st[top]]<=h[i]) top--; ans+=top; st[++top]=i; }printf("%lld ",ans); return 0; }
bzoj 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛——二分
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,x[M]; int check(int k){ int sum=x[1],cnt=1; for(int i=2;i<=n;i++)if(x[i]-sum>=k) cnt++,sum=x[i]; return cnt>=m; } int main() { n=read(); m=read(); for(int i=1;i<=n;i++) x[i]=read(); sort(x+1,x+1+n); int l=0,r=x[n]; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid-1; }printf("%d ",r); return 0; }
bzoj 1679: [Usaco2005 Jan]Moo Volume 牛的呼声——排序
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,x[M]; LL ans; int main() { n=read(); for(int i=1;i<=n;i++) x[i]=read(); sort(x+1,x+1+n); LL sum=x[1]; for(int i=2;i<=n;i++) ans=ans+1LL*(i-1)*x[i]-sum,sum+=x[i]; printf("%lld ",ans*2); return 0; }
bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+Dijkstra
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int N=10007,inf=0x7f7f7f7f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k; int d[N][25]; struct node{ int d,h,pos; bool operator <(const node& x)const{return x.d<d;} }; priority_queue<node>q; int first[N],cnt; struct pos{int to,next,w;}e[10*N]; void ins(int a,int b,int w){e[++cnt]=(pos){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} int dj(){ memset(d,0x7f,sizeof(d)); for(int i=0;i<=k;i++) d[1][i]=0; q.push((node){0,0,1}); while(!q.empty()){ node p=q.top(); q.pop(); if(d[p.pos][p.h]!=p.d) continue; if(p.pos==n) return p.d; int x=p.pos,h=p.h; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d[now][h]>d[x][h]+e[i].w) d[now][h]=d[x][h]+e[i].w,q.push((node){d[now][h],h,now}); if(h<k&&d[now][h+1]>d[x][h]) d[now][h+1]=d[x][h],q.push((node){d[now][h+1],h+1,now}); } } return d[n][k]; } int main() { int x,y,v; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),v=read(),insert(x,y,v); printf("%d ",dj()); return 0; }
bzoj 1711: [Usaco2007 Open]Dining吃饭——网络流
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using namespace std; const int M=1e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k; int S,T,N,ans; int first[M],cur[M],cnt=1; struct node{int to,next,flow;}e[M*M]; void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;} void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);} int d[M]; queue<int>q; int bfs(){ memset(d,-1,sizeof(d)); d[S]=1; q.push(S); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||a==0) return a; int flow=0,f; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } int main() { int x,y,v; n=read(); m=read(); k=read(); S=0; T=n*2+m+k+1; N=n*2; for(int i=1;i<=n;i++) insert(i,i+n,1); for(int i=1;i<=m;i++) insert(S,i+N,1); for(int i=1;i<=k;i++) insert(i+N+m,T,1); for(int i=1;i<=n;i++){ x=read(); y=read(); for(int j=1;j<=x;j++) v=read(),insert(v+N,i,1); for(int j=1;j<=y;j++) v=read(),insert(i+n,v+N+m,1); } while(bfs()){ for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf); }printf("%d ",ans); return 0; }
bzoj 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚——差分
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1e6+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,s[M],l,r,mx; int main() { n=read(); for(int i=1;i<=n;i++){ l=read(); r=read(); mx=max(mx,r); s[l]++; s[r+1]--; } int sum=0,ans=0; for(int i=1;i<=mx;i++) sum+=s[i],ans=max(ans,sum); printf("%d ",ans); return 0; }
bzoj 1690: [Usaco2007 Dec]奶牛的旅行——分数规划+spfa判负环
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } bool f; int n,m,v[M]; int first[M],cnt; struct node{int to,next,w; double h;}e[10*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w,0}; first[a]=cnt;} int vis[M]; double d[M]; void dfs(int x){ vis[x]=1; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d[now]>d[x]+e[i].h){ if(vis[now]){f=true; return ;} d[now]=d[x]+e[i].h; dfs(now); } } vis[x]=0; } bool check(double k){ for(int i=1;i<=cnt;i++) e[i].h=k*e[i].w-v[e[i].to]; for(int i=1;i<=n;i++) d[i]=vis[i]=0; f=false; for(int i=1;i<=n;i++){dfs(i); if(f) return 1;} return 0; } int main() { int x,y,w; n=read(); m=read(); for(int i=1;i<=n;i++) v[i]=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(x,y,w); double l=0.0,r=10000; while(r-l>1e-3){ double mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; }printf("%.2f ",l); return 0; }
bzoj 1708: [Usaco2007 Oct]Money奶牛的硬币——完全背包
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,c[55]; LL f[10007]; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) c[i]=read(); f[0]=1; for(int i=1;i<=n;i++) for(int j=c[i];j<=m;j++) f[j]+=f[j-c[i]]; printf("%lld ",f[m]); return 0; }
bzoj 1634: [Usaco2007 Jan]Protecting the Flowers 护花——贪心
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n; struct node{ int T,d; bool operator <(const node& x)const{return T*x.d<x.T*d;} }e[M]; LL ans,sum; int main() { n=read(); for(int i=1;i<=n;i++) e[i].T=read(),e[i].d=read(),sum+=e[i].d; sort(e+1,e+1+n); for(int i=1;i<=n;i++){ sum-=e[i].d; ans+=2*e[i].T*sum; }printf("%lld ",ans); return 0; }
bzoj 1629: [Usaco2007 Demo]Cow Acrobats——贪心
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,ans,sum; struct node{int w,s;}e[M]; bool cmp(node a,node b){return b.s-a.w>a.s-b.w;} int main() { n=read(); for(int i=1;i<=n;i++) e[i].w=read(),e[i].s=read(); sort(e+1,e+1+n,cmp); ans=-e[1].s; sum=e[1].w; for(int i=2;i<=n;i++){ ans=max(ans,sum-e[i].s); sum+=e[i].w; }printf("%d ",ans); return 0; }
bzoj 1725: [Usaco2006 Nov]Corn Fields牧场的安排——状压dp
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int mod=1e9; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,cnt,ans; int s[15],f[15][20007]; bool pd(int x){return (x&(x<<1))==0;} int main() { n=read(); m=read(); cnt=(1<<m)-1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i]=(s[i]<<1)+(read()^1); for(int i=0;i<=cnt;i++) if(pd(i)&&!(i&s[1])) f[1][i]=1; for(int i=2;i<=n;i++) for(int j=0;j<=cnt;j++) if(!(j&s[i])&&pd(j)) for(int k=0;k<=cnt;k++) if(!(j&k)&&!(k&s[i-1])&&pd(k)) (f[i][j]+=f[i-1][k])%=mod; for(int i=0;i<=cnt;i++) (ans+=f[n][i])%=mod; printf("%d ",ans); return 0; }
bzoj 1620: [Usaco2008 Nov]Time Management 时间管理——贪心
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e3+7,mod=1e9; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,ans=1e6+7; struct node{int T,s;}e[M]; bool cmp(node a,node b){return a.s>b.s;} int main() { n=read(); for(int i=1;i<=n;i++) e[i].T=read(),e[i].s=read(); sort(e+1,e+1+n,cmp); for(int i=1;i<=n;i++) ans=min(ans,e[i].s)-e[i].T; if(ans<0) printf("-1 "); else printf("%d ",ans); return 0; }
bzoj 1827: [Usaco2010 Mar]gather 奶牛大集会——贪心
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e6+7; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,c[M]; LL sz[M],ans,dis[M]; int first[M],cnt; struct node{int to,next; LL w;}e[2*M]; void ins(int a,int b,LL w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);} LL dfs(int x,int fa){ LL sum=dis[x]*c[x]; sz[x]=c[x]; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dis[now]=dis[x]+e[i].w; sum+=dfs(now,x); sz[x]+=sz[now]; } return sum; } void mov(int x,int fa){ for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; if(sz[1]-2*sz[now]<0){ ans+=e[i].w*(sz[1]-2*sz[now]); mov(now,x); return ; } } } int main() { LL x,y,w; n=read(); for(int i=1;i<=n;i++) c[i]=read(); for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w); ans=dfs(1,-1); mov(1,-1); printf("%lld ",ans); return 0; }
bzoj 1639: [Usaco2007 Mar]Monthly Expense 月度开支——二分
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,ans,l,r; int w[M]; int check(int k){ int sum=0,cnt=1; for(int i=1;i<=n;i++) if(sum+w[i]<=k) sum+=w[i]; else{ sum=w[i]; cnt++; if(cnt>m||w[i]>k) return 0; } return 1; } int main() { n=read(); m=read(); for(int i=1;i<=n;i++) w[i]=read(),r+=w[i]; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; }printf("%d ",ans); return 0; }
临时改变计划 silver刷不下去了QAQ 现在先刷gold
bzoj2442: [Usaco2011 Open]修剪草坪——单调队列优化dp
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=100007; const LL inf=1e15; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k; int head,tail,q[M]; LL ans,f[M],h[M],mn=inf; int main() { n=read(); k=read(); for(int i=1;i<=n;i++) h[i]=read(),ans+=h[i]; for(int i=1;i<=n;i++){ f[i]=f[q[head]]+h[i]; while(head<=tail&&f[q[tail]]>f[i]) tail--; q[++tail]=i; while(head<=tail&&i-q[head]>k) head++; } for(int i=n-k;i<=n;i++) mn=min(mn,f[i]); printf("%lld ",ans-mn); return 0; }
bzoj 1592: [Usaco2008 Feb]Making the Grade 路面修整——dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=2007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,s[M],h[M],f[M],ff[M]; int main() { n=read(); for(int i=1;i<=n;i++) s[i]=read(),h[i]=s[i]; sort(h+1,h+1+n); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ f[j]+=abs(s[i]-h[j]); if(j>1) f[j]=min(f[j],f[j-1]); } for(int j=n;j;j--){ ff[j]+=abs(s[i]-h[j]); if(j<n) ff[j]=min(ff[j],ff[j+1]); } } printf("%d ",min(f[n],ff[1])); return 0; }
bzoj 1576: [Usaco2009 Jan]安全路经Travel——dijkstra+并查集
题解我博客有另写 请搜索bzoj 1576(记得加空格) 另外spfa会被卡
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1e5+7,M=4e5+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,ans[N]; int f[N],fa[N]; int find(int x){while(x!=f[x]) x=f[x]=f[f[x]]; return x;} int first[N],cnt,cntq; struct node{int from,to,next,w;}e[M],qs[M]; bool cmp(node a,node b){return a.w<b.w;} void ins(int a,int b,int w){e[++cnt]=(node){a,b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} int dis[N],dep[N]; struct Q{ int d,pos; bool operator <(const Q& x)const{return x.d<d;} }; priority_queue<Q>q; void dj(){ memset(dis,0x3f,sizeof(dis)); q.push((Q){0,1}); dis[1]=0; while(!q.empty()){ Q p=q.top(); q.pop(); if(p.d>dis[p.pos]) continue; int x=p.pos; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(dis[now]>dis[x]+e[i].w){ dis[now]=dis[x]+e[i].w; dep[now]=dep[x]+1; fa[now]=x; q.push((Q){dis[now],now}); } } } //for(int i=1;i<=n;i++) printf("[%d] ",dis[i]); printf(" "); } int main(){ int x,y,w; n=read(); m=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w); dj(); for(int i=1;i<=cnt;i++){ x=e[i].from; y=e[i].to; if(dep[x]<dep[y]) swap(x,y); if(dis[x]==dis[y]+e[i].w) continue; qs[++cntq]=(node){x,y,0,dis[x]+dis[y]+e[i].w}; } sort(qs+1,qs+1+cntq,cmp); for(int i=1;i<=cntq;i++){ x=qs[i].from; y=qs[i].to; while(x!=y){ if(dep[x]<dep[y]) swap(x,y); if(!ans[x]) ans[x]=qs[i].w-dis[x]; x=f[x]=find(fa[x]); //printf("[%d] ",x); } } for(int i=2;i<=n;i++){ if(!ans[i]) printf("-1 "); else printf("%d ",ans[i]); } return 0; }
bzoj 1782: [Usaco2010 Feb]slowdown 慢慢游——dfs序
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=2e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,sum,l[M],r[M],pos[M],k; int first[M],cnt; struct node{int to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void dfs(int x,int fa){ pos[x]=l[x]=++sum; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dfs(now,x); } r[x]=sum; } int s[M]; int lowbit(int x){return x&-x;} int query(int x){ int ans=0; while(x){ans+=s[x]; x-=lowbit(x);} return ans; } void add(int x,int v){ while(x<=n){ s[x]+=v; x+=lowbit(x); } } int main(){ int x,y; n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); dfs(1,0); for(int i=1;i<=n;i++){ k=read(); int lx=l[k],rx=r[k]; printf("%d ",query(pos[k])); add(lx,1); add(rx+1,-1); } return 0; }
bzoj 1596: [Usaco2008 Jan]电话网络——贪心+dfs
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=2e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,n,mark[M]; int first[M],cnt; struct node{int to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void dfs(int x,int fa){ bool f=false; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dfs(now,x); if(mark[now]) f=1; } if(!f&&!mark[x]&&!mark[fa]){ans++; mark[fa]=1;} } int main(){ int x,y; n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); dfs(1,0); printf("%d ",ans); return 0; }
bzoj 1692: [Usaco2007 Dec]队列变换——二分+hash
强行hash代替后缀数组QAQ
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=35007,P=9875321; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,cnt; char s[M],ans[M]; unsigned long long h1[M],h2[M],w[M]; int find(int x,int y){ if(s[x]!=s[y]) return 0; int l=1,r=y-x+1; while(l<r){ int mid=(l+r)>>1; if(h1[x+mid]-h1[x-1]*w[mid+1]==h2[y-mid]-h2[y+1]*w[mid+1]) l=mid+1; else r=mid; }//printf("%d %d [%d] ",x,y,l); return l; } void prepare(){ w[0]=1; for(int i=1;i<=n;i++) w[i]=w[i-1]*P; } int main(){ n=read(); prepare(); for(int i=1;i<=n;i++) scanf("%s",s+i); for(int i=1;i<=n;i++) h1[i]=h1[i-1]*P+s[i]; for(int i=n;i;i--) h2[i]=h2[i+1]*P+s[i]; int l=1,r=n; while(l<=r){ int d=find(l,r); if(s[l+d]<s[r-d]) ans[++cnt]=s[l],l++; else ans[++cnt]=s[r],r--; }//printf("[%d] ",cnt); for(int i=1;i<=cnt;++i){ putchar(ans[i]); if(i%80==0)putchar(10); } return 0; }
bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞——spfa判负环
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=507; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int T,n,m,k,vis[M],d[M]; int first[M],cnt; struct node{int to,next,w;}e[10007]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} bool f; void dfs(int x){ vis[x]=1; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d[now]>d[x]+e[i].w){ if(vis[now]){f=true; return ;} d[now]=d[x]+e[i].w; dfs(now); } } vis[x]=0; } int pd(){ f=false; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ memset(d,0,sizeof(d)); dfs(i); if(f) return 1; } return 0; } int main(){ T=read(); while(T--){ int x,y,w; cnt=0; memset(first,0,sizeof(first)); n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w); for(int i=1;i<=k;i++) x=read(),y=read(),w=read(),ins(x,y,-w); if(pd()) printf("YES "); else printf("NO "); } return 0; }
bzoj 1596: [Usaco2008 Jan]电话网络——贪心
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=2e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,n,mark[M]; int first[M],cnt; struct node{int to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void dfs(int x,int fa){ bool f=false; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dfs(now,x); if(mark[now]) f=1; } if(!f&&!mark[x]&&!mark[fa]){ans++; mark[fa]=1;} } int main(){ int x,y; n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); dfs(1,0); printf("%d ",ans); return 0; }
bzoj 1571: [Usaco2009 Open]滑雪课Ski——dp
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=15007,N=107; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int T,n,m,ans; int s[M],d[M],h[M],mn[N]; int c[M],w[M]; int f[M][N],k[M][N],g[M][N]; int main(){ T=read(); n=read(); m=read(); for(int i=1;i<=n;i++) s[i]=read(),d[i]=read(),h[i]=read(),k[s[i]+d[i]][h[i]]=s[i]; for(int i=1;i<=m;i++) c[i]=read(),w[i]=read(); memset(mn,0x3f,sizeof(mn)); memset(f,-0x3f,sizeof(f)); memset(g,-0x3f,sizeof(g)); for(int i=1;i<=100;i++) for(int j=1;j<=m;j++)if(c[j]<=i) mn[i]=min(mn[i],w[j]); f[0][1]=g[0][1]=0; for(int i=1;i<=T;i++){ for(int j=0;j<=100;j++){ f[i][j]=f[i-1][j]; if(i>=mn[j]) f[i][j]=max(f[i][j],f[i-mn[j]][j]+1); f[i][j]=max(f[i][j],g[k[i][j]][j]); g[i][j]=max(g[i][j-1],f[i][j]); } } for(int i=1;i<=100;i++) ans=max(ans,f[T][i]); printf("%d ",ans); return 0; }
bzoj 1770: [Usaco2009 Nov]lights 燈
1.折半搜索
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int mod=9875321,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans[1<<19],n,m,h,mn=inf; LL p[55],tot; bool f; int first[mod],cnt; struct node{LL v; int next;}e[1<<19]; int get(LL w){ int x=w%mod; for(int i=first[x];i;i=e[i].next) if(e[i].v==w) return i; e[++cnt]=(node){w,first[x]}; first[x]=cnt; return cnt; } void dfs(int x,LL now,int step){ if(x==h+1){ int k; if(now==tot) mn=min(mn,step); if(!f){ k=get(now); if(!ans[k]||ans[k]>step) ans[k]=step; } else{ k=get(tot-now); if(!ans[k]) return ; mn=min(mn,ans[k]+step); } return ; } dfs(x+1,now,step); dfs(x+1,now^p[x],step+1); } int main(){ int x,y; n=read(); m=read(); tot=(1LL<<n)-1; for(int i=1;i<=n;i++) p[i]=1LL<<(i-1); for(int i=1;i<=m;i++){ x=read(); y=read(); p[x]^=1LL<<(y-1); p[y]^=1LL<<(x-1); } f=false; h=n/2; dfs(1,0,0); f=true; h=n; dfs(n/2+1,0,0); printf("%d ",mn); return 0; }
2.高斯消元——待填
bzoj 1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富——dp(最长路)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=107,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,now; int s[N][N],d[N][N]; int main(){ n=read(); m=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i][j]=read(); memset(d,-0x3f,sizeof(d)); d[1][1]=s[1][1]; for(int i=2;i<=m;i++) for(int j=1;j<=n;j++){ now=j-1;if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]); now=j; if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]); now=j+1;if(now>=1&&now<=n) d[j][i]=max(d[j][i],d[now][i-1]+s[j][i]); } printf("%d ",d[n][m]); return 0; }
bzoj 1691: [Usaco2007 Dec]挑剔的美食家——贪心+平衡树
#include<cstdio> #include<cstring> #include<algorithm> #include<set> #define LL long long const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m; LL ans; struct node{ int w,c; bool operator <(const node& x)const{return x.c<c;} }e[M],q[M]; std::multiset<int>tr; std::multiset<int>::iterator it; int main(){ n=read(); m=read(); for(int i=1;i<=n;i++) e[i].w=read(),e[i].c=read(); for(int i=1;i<=m;i++) q[i].w=read(),q[i].c=read(); std::sort(e+1,e+1+n); std::sort(q+1,q+1+m); int k=1; for(int i=1;i<=n;i++){ while(k<=m&&q[k].c>=e[i].c) tr.insert(q[k++].w); it=tr.lower_bound(e[i].w); if(it!=tr.end()) ans+=*it,tr.erase(it); else return puts("-1"),0; }printf("%lld ",ans); return 0; }
bzoj 1593: [Usaco2008 Feb]Hotel 旅馆——线段树
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=1<<17; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int k,d,n,m,L,R; struct node{int l,r,lr,rl,mx,h[2];}tr[M]; void up(int x){ int l=x<<1,r=x<<1^1; tr[x].lr=tr[l].lr; if(tr[l].lr==tr[l].r-tr[l].l+1) tr[x].lr=tr[l].lr+tr[r].lr; tr[x].rl=tr[r].rl; if(tr[r].rl==tr[r].r-tr[r].l+1) tr[x].rl=tr[r].rl+tr[l].rl; tr[x].mx=max(max(tr[l].mx,tr[r].mx),tr[l].rl+tr[r].lr); } void calc(int x){ tr[x].lr=tr[x].rl=tr[x].mx=0; tr[x].h[0]=1; tr[x].h[1]=0; } void calc1(int x){ tr[x].lr=tr[x].rl=tr[x].mx=tr[x].r-tr[x].l+1; tr[x].h[1]=1; tr[x].h[0]=0; } void down(int x){ int l=x<<1,r=x<<1^1; if(tr[x].h[0]){ calc(l); calc(r); tr[x].h[0]=0; } if(tr[x].h[1]){ calc1(l); calc1(r); tr[x].h[1]=0; } } void build(int x,int l,int r){ tr[x].l=l; tr[x].r=r; if(l==r){ tr[x].lr=tr[x].rl=tr[x].mx=1; return ; } int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1^1,mid+1,r); up(x); } void modify(int x,int s){ if(L<=tr[x].l&&tr[x].r<=R){ if(s==0) calc(x); else calc1(x); return ; } down(x); int mid=(tr[x].l+tr[x].r)>>1; if(L<=mid) modify(x<<1,s); if(R>mid) modify(x<<1^1,s); up(x); } int find(int x,int d){ down(x); int l=x<<1,r=x<<1^1,mid=(tr[x].l+tr[x].r)>>1; if(tr[x].l==tr[x].r) return l; if(tr[l].mx>=d) return find(l,d); if(tr[l].rl+tr[r].lr>=d) return mid-tr[l].rl+1; return find(r,d); } int main(){ n=read(); m=read(); build(1,1,n); for(int i=1;i<=m;i++){ k=read(); if(k==1){ d=read(); if(tr[1].mx<d) printf("0 "); else{ int y=find(1,d); printf("%d ",y); L=y; R=y+d-1; modify(1,0); } } else{ L=read(); R=L+read()-1; modify(1,1); } } return 0; }
bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居——排序+贪心+set
#include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<queue> using namespace std; const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,c; int f[M],h[M],ans,mx; int find(int x){while(f[x]!=x) x=f[x]=f[f[x]]; return x;} struct node{ int x,y,id; bool operator <(const node& k)const{return x<k.x;} }e[M]; struct pos{ int y,id; bool operator <(const pos& k)const{return y!=k.y?y<k.y:id<k.id;} }; std::queue<int>q; std::multiset<pos>tr; std::multiset<pos>::iterator it; int main(){ int x,y; n=read(); c=read(); for(int i=1;i<=n;i++){ x=read(); y=read(); f[i]=i; e[i].x=x+y,e[i].y=x-y; e[i].id=i; } sort(e+1,e+1+n); for(int i=1;i<=n;i++){ while(!q.empty()&&e[i].x-e[q.front()].x>c){ int now=q.front(); q.pop(); tr.erase(tr.find((pos){e[now].y,e[now].id})); } q.push(i); it=tr.insert((pos){e[i].y,e[i].id}); if(it!=tr.begin()){ --it; if(e[i].y-(it->y)<=c){ int p=find(e[i].id),q=find(it->id); f[q]=p; } ++it; } ++it; if(it!=tr.end()){ if(it->y-e[i].y<=c){ int p=find(e[i].id),q=find(it->id); f[q]=p; } } } for(int i=1;i<=n;i++){ int x=find(e[i].id); if(!h[x]) ans++; h[x]++; mx=max(mx,h[x]); }printf("%d %d ",ans,mx); return 0; }
bzoj 1697: [Usaco2007 Feb]Cow Sorting牛排序——置换
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=10007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,v[M],s[M],vis[M],ans; void mins(int &x,int y){if(y<x) x=y;} int min(int x,int y){return x<y?x:y;} int main(){ n=read(); for(int i=1;i<=n;i++) v[i]=s[i]=read(); sort(s+1,s+1+n); for(int i=1;i<=n;i++)if(!vis[i]){ int mn=v[i],sum=v[i],now=i,h=1; while(1){ vis[now=lower_bound(s+1,s+1+n,v[now])-s]=1; if(now==i) break; h++; mins(mn,v[now]); sum+=v[now]; } ans=ans+min((sum-mn)+(h-1)*mn,(s[1]+mn)*2+(sum-mn)+(h-1)*s[1]); }printf("%d ",ans); return 0; }
bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果——拓扑排序求基环树
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,to[M],in[M],stk[M],top,f[M]; int head,tail,q[M]; int main(){ n=read(); for(int i=1;i<=n;i++) to[i]=read(),in[to[i]]++; for(int i=1;i<=n;i++) if(!in[i]) q[tail++]=i; while(head<=tail){ int x=q[head++],now=to[x]; in[now]--; if(!in[now]) q[tail++]=now; } for(int i=1;i<=n;i++)if(in[i]){ int now=i,h=1; stk[top=1]=i; in[i]=0; while(1){ now=to[now]; if(now==i) break; h++; in[now]=0; stk[++top]=now; } while(top) f[stk[top]]=h,top--; } while(tail>0) tail--,f[q[tail]]=f[to[q[tail]]]+1; for(int i=1;i<=n;i++) printf("%d ",f[i]); return 0; }
bzoj 1574: [Usaco2009 Jan]地震损坏Damage——贪心+搜索
因为你一个点附近的点如果能够使其他点到达1那他也一定可以然这个点到达1
所以把走不到1的点全部删掉然后dfs一次就行了
#include<cstdio> #include<cstring> #include<algorithm> const int M=35007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,ans; int first[M],cnt,mark[M],vis[M]; struct node{int to,next;}e[10*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void delet(int x){for(int i=first[x];i;i=e[i].next) mark[e[i].to]=1;} void dfs(int x){ vis[x]=1; ans--; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!mark[now]&&!vis[now]) dfs(now); } } int main(){ int x,y; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y); for(int i=1;i<=k;i++) x=read(),delet(x); ans=n; dfs(1); printf("%d ",ans); return 0; }
bzoj 1707: [Usaco2007 Nov]tanning分配防晒霜——排序贪心
#include<cstdio> #include<cstring> #include<algorithm> #include<set> const int M=2507; char buf[M*44],*ptr=buf-1; int read(){ int ans=0,f=1,c=*++ptr; while(c<'0'||c>'9'){if(c=='-') f=-1; c=*++ptr;} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;} return ans*f; } int n,m,ans; struct node{ int l,r; bool operator <(const node& x)const{return r<x.r;} }e[M]; struct pos{ int w,h; bool operator <(const pos& x)const{return w<x.w;} }q[M]; struct Q{ int w,id; bool operator <(const Q& x)const{return w!=x.w?w<x.w:id<x.id;} }; std::multiset<Q>tr; std::multiset<Q>::iterator it; int main(){ fread(buf,1,sizeof(buf),stdin); n=read(); m=read(); for(int i=1;i<=n;i++) e[i].l=read(),e[i].r=read(); std::sort(e+1,e+1+n); for(int i=1;i<=m;i++) q[i].w=read(),q[i].h=read(); std::sort(q+1,q+1+m); int k=1; for(int i=1;i<=n;i++){ while(k<=m&&q[k].w<=e[i].r) tr.insert((Q){q[k].w,k}),k++; it=tr.lower_bound((Q){e[i].l,-1}); if(it!=tr.end()){ ans++; q[it->id].h--; if(!q[it->id].h) tr.erase(it); } }printf("%d ",ans); return 0; }
bzoj 1709: [Usaco2007 Oct]Super Paintball超级弹珠——暴力
#include<cstdio> #include<cstring> #include<algorithm> const int M=157; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,s[9][M][M],f[M][M],ans; int main(){ int x,y; n=read(); k=read(); for(int i=1;i<=k;i++){ x=read(); y=read(); f[x][y]++; for(int k=1;k<=8;k++) s[k][x][y]++; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ s[1][i][j]+=s[1][i][j-1]; s[2][i][j]+=s[2][i-1][j-1]; s[3][i][j]+=s[3][i-1][j]; s[4][i][j]+=s[4][i-1][j+1]; } for(int i=n;i;i--) for(int j=n;j;j--){ s[5][i][j]+=s[5][i][j+1]; s[6][i][j]+=s[6][i+1][j-1]; s[7][i][j]+=s[7][i+1][j]; s[8][i][j]+=s[8][i+1][j+1]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ for(int k=1;k<=8;k++) s[0][i][j]+=s[k][i][j]; if(f[i][j]) s[0][i][j]-=7*f[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)if(s[0][i][j]==k) ans++; printf("%d ",ans); return 0; }
bzoj 1828: [Usaco2010 Mar]balloc 农场分配——线段树
#include<cstdio> #include<cstring> #include<algorithm> const int M=1e5+7,N=1<<18,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,ans,L,R; struct node{int l,r;}q[M]; bool cmp(node a,node b){return a.r!=b.r?a.r<b.r:a.l>b.l;} struct pos{int l,r,mn,tag;}tr[N]; void up(int x){tr[x].mn=std::min(tr[x<<1].mn,tr[x<<1^1].mn);} void down(int x){ if(tr[x].tag){ int v=tr[x].tag; tr[x].tag=0; tr[x<<1].tag+=v; tr[x<<1^1].tag+=v; tr[x<<1].mn-=v; tr[x<<1^1].mn-=v; } } void build(int x,int l,int r){ tr[x].l=l; tr[x].r=r; if(l==r){tr[x].mn=read();return ;} int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1^1,mid+1,r); up(x); } int pmin(int x){ if(L<=tr[x].l&&tr[x].r<=R) return tr[x].mn; int mid=(tr[x].l+tr[x].r)>>1,mn=inf; down(x); if(L<=mid) mn=std::min(mn,pmin(x<<1)); if(R>mid) mn=std::min(mn,pmin(x<<1^1)); return mn; } void modify(int x){ if(L<=tr[x].l&&tr[x].r<=R){tr[x].mn-=1; tr[x].tag++; return ;} int mid=(tr[x].l+tr[x].r)>>1; down(x); if(L<=mid) modify(x<<1); if(R>mid) modify(x<<1^1); up(x); } int main(){ n=read(); m=read(); build(1,1,n); for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(); std::sort(q+1,q+1+m,cmp); for(int i=1;i<=m;i++){ L=q[i].l; R=q[i].r; if(pmin(1)>=1) ans++,modify(1); }printf("%d ",ans); return 0; }
bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑——倍增floyd(裸
#include<cstdio> #include<cstring> #include<algorithm> const int M=1e3+7,inf=0x3f3f3f3f,mod=29399; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,S,T; int first[mod],cnt; struct node{int v,next;}e[M]; int get(int w){ int x=w%mod; for(int i=first[x];i;i=e[i].next) if(e[i].v==w) return i; e[++cnt]=(node){w,first[x]}; first[x]=cnt; return cnt; } void mins(int &x,int y){if(x>y) x=y;} typedef int mat[M][M]; mat f,ans,tmp; void floyd(mat b,mat c){ memset(tmp,0x3f,sizeof(mat)); for(int i=1;i<=cnt;i++) for(int k=1;k<=cnt;k++) for(int j=1;j<=cnt;j++) mins(tmp[i][j],b[i][k]+c[k][j]); memcpy(b,tmp,sizeof(mat)); } int main(){ int x,y,w; memset(f,0x3f,sizeof(mat)); n=read(); m=read(); S=get(read()); T=get(read()); for(int i=1;i<=m;i++) w=read(),x=get(read()),y=get(read()),f[x][y]=f[y][x]=std::min(f[x][y],w); memset(ans,0x3f,sizeof(mat)); for(int i=1;i<=cnt;i++) ans[i][i]=0; for(;n;n>>=1,floyd(f,f)) if(n&1) floyd(ans,f); printf("%d ",ans[S][T]); return 0; }
bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生——$nsqrt(n)$ DP
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define LL long long const int M=40007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,d; int c[M],last[M],now[M],q[M],f[M]; void mins(int &x,int y){if(x>y) x=y;} int main(){ n=read(); m=read(); d=sqrt(n); for(int i=1;i<=m;i++) last[i]=-1; for(int i=1;i<=n;i++) c[i]=read(),now[i]=last[c[i]],last[c[i]]=i; for(int i=1;i<=n;i++){ int k=1; while(k<=d&&q[k]>now[i]) k++; k--; f[i]=i; q[0]=i; for(int j=std::min(k,d);j;j--) q[j]=q[j-1]; for(int j=1;j<=d;j++) mins(f[i],f[q[j]-1]+j*j); }printf("%d ",f[n]); return 0; }
bzoj 1754: [Usaco2005 qua]Bull Math——高精度x高精度
#include<cstdio> #include<cstring> #include<algorithm> const int M=55; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } char s1[M],s2[M]; int cnt1,cnt2,b[M],c[M],ans[2*M],cntq; int main(){ scanf("%s%s",s1,s2); cnt1=strlen(s1); cnt2=strlen(s2); for(int i=0;i<cnt1;++i) b[i]=s1[cnt1-i-1]-'0'; for(int i=0;i<cnt2;++i) c[i]=s2[cnt2-i-1]-'0'; cntq=cnt1+cnt2; for(int i=0;i<cnt1;--i){ for(int j=0;j<cnt2;j++){ ans[i+j]+=b[i]*c[j]; } } for(int i=0;i<cntq;++i){ ans[i+1]+=ans[i]/10; ans[i]%=10; } while(!ans[cntq]&&cntq) --cntq; for(int i=cntq;i>=0;--i) printf("%d",ans[i]); return 0; }
bzoj 1753: [Usaco2005 qua]Who's in the Middle——STL nth_element
#include<cstdio> #include<cstring> #include<algorithm> const int M=10007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,s[M]; int main(){ n=read(); k=n/2; for(int i=0;i<n;i++) s[i]=read(); std::nth_element(s,s+k,s+n); printf("%d ",s[k]); return 0; }
bzoj 1710: [Usaco2007 Open]Cheappal 廉价回文——dp
#include<cstdio> #include<cstring> #include<algorithm> using std::min; const int M=3e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,cnt; int f[M][35],cost[M]; char s[M],ch[15]; int main(){ int x,y; n=read(); m=read(); scanf("%s",s+1); cnt=strlen(s+1); for(int i=1;i<=n;i++){ scanf("%s",ch); x=read(); y=read(); cost[(int)ch[0]]=min(x,y); } for(int k=1;k<m;k++){ for(int l=1;l<=m-k;l++){ int r=l+k; f[l][r]=min(f[l+1][r]+cost[(int)s[l]],f[l][r-1]+cost[(int)s[r]]); if(s[l]==s[r]) f[l][r]=min(f[l][r],f[l+1][r-1]); } }printf("%d ",f[1][m]); return 0; }
bzoj 1598: [Usaco2008 Mar]牛跑步——第K短路
#include<cstdio> #include<cstring> #include<algorithm> const int M=2e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,h[M],d[M][105]; int first[M],cnt; struct node{int to,next,w;}e[10*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void merge(int s1[M],int s2[M],int w){ memset(h,0,sizeof(h)); int cnt=0,l=1,r=1; while(cnt<k){ if(s1[l]<s2[r]+w) h[++cnt]=s1[l++]; else h[++cnt]=s2[r]+w,r++; } for(int i=1;i<=k;i++) s1[i]=h[i]; } int main(){ int x,y,w; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),ins(y,x,w); memset(d,0x3f,sizeof(d)); d[n][1]=0; for(int x=n-1;x;x--){ for(int i=first[x];i;i=e[i].next){ int now=e[i].to; merge(d[x],d[now],e[i].w); } } for(int i=1;i<=k;i++) if(d[1][i]==inf) printf("-1 "); else printf("%d ",d[1][i]); return 0; }
bzoj 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛——树形dp
#include<cstdio> #include<cstring> #include<algorithm> using std::max; const int M=50007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,f[M][2]; int first[M],cnt; struct node{int to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void dfs(int x,int fa){ f[x][1]=1; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dfs(now,x); f[x][0]=f[x][0]+max(f[now][0],f[now][1]); f[x][1]=f[x][1]+f[now][0]; } } int main(){ int x,y; n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); dfs(1,-1); printf("%d ",max(f[1][0],f[1][1])); return 0; }
bzoj 1741: [Usaco2005 nov]Asteroids 穿越小行星群——网络流
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using std::min; const int M=2e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,cur[M],d[M]; int S,T,ans; int first[M],cnt=1; struct node{int to,next,flow;}e[20*M]; void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;} void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);} std::queue<int>q; int bfs(){ memset(d,-1,sizeof(d)); d[S]=1; q.push(S); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||a==0) return a; int flow=0,f; for(int& i=cur[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } int main(){ int x,y; n=read(); k=read(); S=0; T=2*n+1; for(int i=1;i<=n;i++) insert(S,i,1); for(int i=1;i<=n;i++) insert(i+n,T,1); for(int i=1;i<=k;i++) x=read(),y=read(),insert(x,y+n,1); while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);} printf("%d ",ans); return 0; }
bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名——floyd传递闭包
#include<cstdio> #include<cstring> #include<algorithm> #include<bitset> int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,x,y,ans; std::bitset<1007> f[1007]; int main(){ n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) if(f[i][k]) f[i]|=f[k]; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)if(!f[i][j]&&!f[j][i]) ans++; printf("%d ",ans); return 0; }
bzoj 1578: [Usaco2009 Feb]Stock Market 股票市场——dp(完全背包
#include<cstdio> #include<cstring> #include<algorithm> using std::max; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,mx; int f[550007],map[105][105]; int main(){ n=read(); m=read(); k=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) map[j][i]=read(); mx=k; for(int i=2;i<=m;i++){ memset(f,0,sizeof(f)); for(int j=1;j<=n;j++) { //printf("%d %dQWQ ",map[i-1][j],mx); for(int k=map[i-1][j];k<=mx;k++) f[k]=max(f[k],f[k-map[i-1][j]]+(map[i][j]-map[i-1][j])); } mx+=f[mx]; //printf("QAQ%d ",mx); } printf("%d ",mx); return 0; }
bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名——floyd传递闭包
#include<cstdio> #include<cstring> #include<algorithm> #include<bitset> int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,x,y,ans; std::bitset<1007> f[1007]; int main(){ n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),f[x][y]=1; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) if(f[i][k]) f[i]|=f[k]; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)if(!f[i][j]&&!f[j][i]) ans++; printf("%d ",ans); return 0; }
bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害——最小割
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> const int M=25007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int first[M],cur[M],cnt=1,ans; int n,m,h,S,T,mark[M]; struct node{int to,next,flow;}e[10*M]; void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;} void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);} std::queue<int>q; int d[M]; int bfs(){ memset(d,-1,sizeof(d)); d[S]=0; q.push(S); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==-1&&e[i].flow) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||a==0) return a; int flow=0,f; for(int& i=cur[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==d[x]+1&&(f=dfs(now,std::min(e[i].flow,a)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } int main(){ int x,y; n=read(); m=read(); h=read(); S=0; T=2*n+1; insert(S,1,inf); insert(1,1+n,inf); for(int i=1;i<=m;i++){ x=read(); y=read(); if(x==y) continue; insert(x+n,y,inf); insert(y+n,x,inf); } for(int i=1;i<=h;i++){ x=read(); mark[x]=1; insert(x,x+n,inf); insert(x+n,T,inf); } for(int i=2;i<=n;i++) if(!mark[i]) insert(i,i+n,1); while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);} printf("%d ",ans); return 0; }
bzoj 1704: [Usaco2007 Mar]Face The Right Way 自动转身机——O(n)枚举O(n)计算就可以了
#include<cstdio> #include<cstring> #include<algorithm> const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,f[M],s[M],ansm,ansk=1; char ch[5]; bool flag; int main(){ n=read(); for(int i=1;i<=n;i++){ scanf("%s",ch); if(ch[0]=='B') s[i]=1,ansm++; } for(int k=1;k<=n;k++){ flag=false; int sum=0,now=0; for(int i=1;i<=n-k+1;i++){ if(f[i]==k) now^=1; if(s[i]^now) sum++,now^=1,f[i+k]=k; } for(int i=n-k+2;i<=n;i++){ if(f[i]==k) now^=1; if(s[i]^now){flag=true; break;} } if(flag) continue; if(sum<ansm) ansm=sum,ansk=k; } printf("%d %d ",ansk,ansm); return 0; }
bzoj 2199: [Usaco2011 Jan]奶牛议会——2—SAT
#include<cstdio> #include<cstring> #include<algorithm> using std::min; const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int qread(){ int x=read(),c=getchar(); while(c!='Y'&&c!='N') c=getchar(); if(c=='Y') return x<<1^1; return x<<1; } int n,m; int first[M],cnt,star[M],sum; struct node{int from,to,next;}e[2*M],q[2*M]; void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;} void qins(int a,int b){q[++sum]=(node){a,b,star[a]}; star[a]=sum;} int qc,color[M],dfn[M],low[M],stk[M],last[M],top,tot; void tarjan(int x){ dfn[x]=low[x]=++tot; stk[++top]=x; last[x]=top; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!dfn[now]) tarjan(now),low[x]=min(low[x],low[now]); else if(!color[now]) low[x]=min(low[x],dfn[now]); } if(low[x]==dfn[x]){ qc++; while(top>=last[x]) color[stk[top]]=qc,top--; } } int h,vis[M]; void dfs(int x){ vis[x]=h; for(int i=star[x];i;i=q[i].next){ int now=q[i].to; if(vis[now]!=h) dfs(now); } } int pd(int x){ h++; dfs(x); for(int i=1;i<=n;i++)if(vis[color[i<<1]]==h&&vis[color[i<<1^1]]==h) return 0; return 1; } char ans[M]; int main(){ int x,y; n=read(); m=read(); for(int i=1;i<=m;i++){ x=qread(); y=qread(); ins(x^1,y); ins(y^1,x); } for(int i=2;i<=(n<<1^1);i++)if(!dfn[i]) tarjan(i); for(int i=1;i<=cnt;i++)if(color[e[i].from]!=color[e[i].to]) qins(color[e[i].from],color[e[i].to]); for(int i=1;i<=n;i++){ if(color[i<<1]==color[i<<1^1]) return puts("IMPOSSIBLE"),0; int p=pd(color[i<<1]),q=pd(color[i<<1^1]); if(!p&&!q) return puts("IMPOSSIBLE"),0; if(p&&q) ans[i]='?'; else if(p) ans[i]='N'; else if(q) ans[i]='Y'; } for(int i=1;i<=n;i++) printf("%c",ans[i]); return 0; }
bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列——hash+map
这道题 转2进制后求前缀和,前缀和的每位都减去第一位,如果有两个前缀和 i 和 j 相同的话,那么i+1~j这一段的k种颜色出现次数一样多
这道题有单独的题解QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<map> #define LL unsigned long long const int M=2e5+7,P=233; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,ans; int d[M][35]; std::map<LL,int>q; int find(int x){ LL sum=0; for(int i=2;i<=k;i++) sum=sum*P+1LL*d[x][i]; if(!q[sum]&&sum) q[sum]=x; return q[sum]; } int main(){ n=read(); k=read(); for(int i=1;i<=n;i++){ int now=0,x=read(); for(;x;x>>=1) d[i][++now]=x&1; for(int j=1;j<=k;j++) d[i][j]+=d[i-1][j]; } for(int i=1;i<=n;i++){ for(int j=2;j<=k;j++) d[i][j]-=d[i][1]; ans=std::max(ans,i-find(i)); }printf("%d ",ans); return 0; }
bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径——边双连通分量缩点求出叶子数
#include<cstdio> #include<cstring> #include<cstring> #include<algorithm> using std::min; const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,f[5*M]; int dfn[M],low[M],last[M],stk[M],top; int color[M],hc,T; int first[M],cnt=1,star[M],sum=1; struct node{int from,to,next;}e[5*M],q[5*M]; void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void insq(int a,int b){q[++sum]=(node){a,b,star[a]}; star[a]=sum;} void insertq(int a,int b){insq(a,b); insq(b,a);} void tarjan(int x){ low[x]=dfn[x]=++T; stk[++top]=x; last[x]=top; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(f[i^1]) continue; f[i]=1; if(!dfn[now]) tarjan(now),low[x]=min(low[x],low[now]); else if(!color[now]) low[x]=min(low[x],dfn[now]); } if(low[x]==dfn[x]) for(hc++;top>=last[x];top--) color[stk[top]]=hc; } int in[M],vis[M],ans; int main(){ int x,y; n=read(); m=read(); for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=2;i<=cnt;i+=2) if(color[e[i].from]!=color[e[i].to]) in[color[e[i].from]]++,in[color[e[i].to]]++; for(int i=1;i<=hc;i++) if(in[i]==1) ans++; printf("%d ",(ans+1)>>1); return 0; }
bzoj 1700: [Usaco2007 Jan]Problem Solving 解题——dp
#include<cstdio> #include<cstring> #include<algorithm> using std::min; const int M=557,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans=inf,n,m,f[M][M]; int k,s1[M],s2[M]; int main(){ memset(f,0x3f,sizeof(f)); n=read(); m=read(); for(int i=1;i<=m;i++){ k=read(); s1[i]=s1[i-1]+k; k=read(); s2[i]=s2[i-1]+k; } f[0][0]=0;f[1][1]=1;f[1][0]=2; for(int k=2;k<=m;k++){ for(int i=1;i<=k;i++)if(s1[k]-s1[k-i]<=n) for(int j=0;j<=k-i;j++)if((s1[k]-s1[k-i])+(s2[k-i]-s2[k-i-j])<=n) f[k][i]=std::min(f[k][i],f[k-i][j]+1); for(int i=1;i<=m;i++)if(s2[k]-s2[k-i]<=n)f[k][0]=min(f[k][0],f[k][i]+1); } ans=f[m][0]+1; for(int i=1;i<=m;i++) if(s2[m]-s2[m-i]<=n) ans=min(ans,f[m][i]+2); printf("%d ",ans); return 0; }
bzoj 1776: [Usaco2010 Hol]cowpol 奶牛政坛——树的直径QAQ
可以证明一个结论 一棵树的直径必然存在一条过深度最深的点
所以我们可以求出每种颜色最深的点 然后其他点和他求一波lca算答案就可以了
这样的复杂度是nlogn的
#include<cstdio> #include<cstring> #include<algorithm> const int M=3e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int rt,n,k,c[M],mx[M],id[M]; int first[M],cnt; struct node{int to,next;}e[M]; int f[M][32],fa[M],dep[M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void dfs(int x){//printf("[%d] ",x); for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1]; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; dep[now]=dep[x]+1; f[now][0]=x; if(dep[now]>mx[c[now]]) mx[c[now]]=dep[now],id[c[now]]=now; dfs(now); } } int find(int x,int y){ if(dep[x]<dep[y]) std::swap(x,y); int d=dep[x]-dep[y]; for(int i=0;(1<<i)<=d;i++) if((1<<i)&d) x=f[x][i]; if(x==y) return x; for(int i=30;i>=0;i--) if((1<<i)<=dep[x]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } int ans[M]; int main(){ int x,y; n=read(); k=read(); for(int i=1;i<=n;i++){ c[i]=read(); fa[i]=read(); if(fa[i]) ins(fa[i],i); else rt=i; } dep[rt]=1; dfs(rt); for(int i=1;i<=n;i++){ int lca=find(i,id[c[i]]); ans[c[i]]=std::max(ans[c[i]],dep[i]+dep[id[c[i]]]-2*dep[lca]); } for(int i=1;i<=k;i++) printf("%d ",ans[i]); return 0; }
bzoj 1778: [Usaco2010 Hol]Dotp 驱逐猪猡——高斯消元+概率dp(待填QAQ
bzoj 3126: [Usaco2013 Open]Photo——单调队列优化dp
#include<cstdio> #include<cstring> #include<algorithm> using std::min; using std::max; const int M=250007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,x,y; int l[M],r[M],f[M]; int q[M],ql=1,qr; int main(){ n=read(); m=read(); for(int i=1;i<=n+1;i++) r[i]=i-1; for(int i=1;i<=m;i++){ x=read(); y=read(); r[y]=min(r[y],x-1); l[y+1]=max(l[y+1],x); } for(int i=n;i;i--) r[i]=min(r[i],r[i+1]); for(int i=2;i<=n+1;i++) l[i]=max(l[i],l[i-1]); f[qr=1]=0; for(int i=1;i<=n+1;i++){ for(int k=r[i-1]+1;k<=r[i];k++){ while(ql<=qr&&f[q[qr]]<=f[k]) qr--; q[++qr]=k; } while(ql<=qr&&q[ql]<l[i]) ql++; if(ql>qr) f[i]=-inf; else f[i]=f[q[ql]]+1; } if(f[n+1]>=0) printf("%d ",f[n+1]-1); else printf("-1 "); return 0; }
当然这道题也有差分约束的写法QAQ——其实是硬水过去的QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using std::queue; const int M=250007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } bool f=false; int ans,n,m; int first[M],cnt; struct node{int to,next,w;}e[5*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} int dis[M],vis[M]; struct pos{int dis,id;}; bool operator <(pos a,pos b){return a.dis>b.dis;}; std::priority_queue<pos>q; void spfa(){ memset(dis,0x3f,sizeof(dis)); q.push((pos){0,0}); dis[0]=0; vis[0]=1; while(!q.empty()){ pos x=q.top(); q.pop(); for(int i=first[x.id];i;i=e[i].next){ int now=e[i].to; if(dis[now]>dis[x.id]+e[i].w){ ans++; if(ans>300000) return void(f=true); dis[now]=dis[x.id]+e[i].w; if(!vis[now]) vis[now]=1,q.push((pos){dis[now],now}); } } vis[x.id]=0; } } int main(){ int l,r; n=read(); m=read(); for(int i=1;i<=m;i++) l=read(),r=read(),ins(l-1,r,1),ins(r,l-1,-1); for(int i=1;i<=n;i++) ins(i-1,i,1),ins(i,i-1,0); spfa(); if(f) printf("-1 "); else printf("%d ",dis[n]); return 0; }
bzoj 1731: [Usaco2005 dec]Layout 排队布局——差分约束
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #define LL long long const int M=1e3+7,N=1e5+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,ml,md,h[M],vis[M]; int x,y,w,dis[M]; int first[M],cnt; struct node{int to,next,w;}e[N]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} std::queue<int>q; bool f=false; void spfa(){ memset(dis,0x3f,sizeof(dis)); q.push(1); dis[1]=0; vis[1]=1; h[1]=1; while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(dis[now]>dis[x]+e[i].w){ dis[now]=dis[x]+e[i].w; if(!vis[now]){ vis[now]=1; q.push(now); h[now]++; if(h[now]==n){f=true; return ;} } } } vis[x]=0; } } int main(){ n=read(); ml=read(); md=read(); for(int i=1;i<=ml;i++) x=read(),y=read(),w=read(),ins(x,y,w); for(int i=1;i<=md;i++) x=read(),y=read(),w=read(),ins(y,x,-w); for(int i=1;i<n;i++) ins(i+1,i,0); spfa(); if(f) printf("-1 "); else if(dis[n]==inf) printf("-2 "); else printf("%d ",dis[n]); return 0; }
bzoj 1705: [Usaco2007 Nov]Telephone Wire 架设电话线——dp
#include<cstdio> #include<cstring> #include<algorithm> using std::min; using std::max; const int M=1e5+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,c,ans,mn; int h[M],f[M][107]; int main(){ n=read(); c=read(); for(int i=1;i<=n;i++) h[i]=read(); memset(f,0x3f,sizeof(f)); for(int i=h[1];i<=100;i++) f[1][i]=(h[1]-i)*(h[1]-i); for(int k=2;k<=n;k++){ mn=inf; for(int i=h[k-1];i<max(h[k-1],h[k]);i++) mn=min(mn,f[k-1][i]-c*i); for(int i=h[k];i<=100;i++){ mn=min(mn,f[k-1][i]-c*i); f[k][i]=mn+c*i+(h[k]-i)*(h[k]-i); } mn=inf; for(int i=100;i>=h[k];i--){ if(i>=h[k-1]) mn=min(mn,f[k-1][i]+c*i); f[k][i]=min(f[k][i],mn-c*i+(h[k]-i)*(h[k]-i)); } } ans=inf; for(int i=1;i<=100;i++) ans=min(ans,f[n][i]); printf("%d ",ans); return 0; }
bzoj 1755: [Usaco2005 qua]Bank Interest-.....
#include<cstdio> #include<cstring> #include<algorithm> double R,M; int y; int main(){ scanf("%lf %lf %d",&R,&M,&y); for(int i=1;i<=y;i++) M=M*(1+R/100); printf("%d ",(int)M); return 0; }
bzoj 2200: [Usaco2011 Jan]道路和航线
1——spfa+SLF优化QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> const int M=3e4+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } bool f=false; int n,nr,np,S; int first[M],cnt; struct node{int to,next,w;}e[7*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} int dis[M],vis[M]; int q[M],head,tail=1; void spfa(){ memset(dis,0x3f,sizeof(dis)); dis[S]=0; vis[S]=1; q[head]=S; while(head!=tail){ int x=q[head++]; if(head>M) head=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(dis[now]>dis[x]+e[i].w){ dis[now]=dis[x]+e[i].w; if(!vis[now]){ vis[now]=1; if(dis[now]<=dis[q[head]]){ head--; if(head<0) head=M; q[head]=now; } else{q[tail++]=now; if(tail>M) tail=0;} } } } vis[x]=0; } for(int i=1;i<=n;i++) if(dis[i]>=inf) printf("NO PATH "); else printf("%d ",dis[i]); } int main(){ int x,y,w; n=read(); nr=read(); np=read(); S=read(); for(int i=1;i<=nr;i++) x=read(),y=read(),w=read(),insert(x,y,w); for(int i=1;i<=np;i++) x=read(),y=read(),w=read(),ins(x,y,w); spfa(); return 0; }
2——dfs染色+拓扑+dijkstra
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> const int M=3e4+7,inf=0x3f3f3f3f; char buf[88*M],*ptr=buf-1; int read(){ int ans=0,f=1,c=*++ptr; while(c<'0'||c>'9'){if(c=='-') f=-1; c=*++ptr;} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;} return ans*f; } bool flag=false; int n,nr,np,S; int first[M],cnt; struct node{int to,next,w;}e[5*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} int color[M],hc; void dfs(int x){ color[x]=hc; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!color[now]) dfs(now); } } int sum,star[M]; struct pos{int from,to,next,w;}q[5*M]; void insq(int a,int b,int w){q[++sum]=(pos){a,b,star[a],w}; star[a]=sum;} int f[M],vis[M]; void find(int x){ vis[x]=f[color[x]]=n+1; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!vis[now]) find(now); } } int k,dis[M],wh[M],mark[5*M]; struct QAQ{ int d,id; bool operator <(const QAQ& x)const{return x.d<d;} }; std::priority_queue<QAQ>qu[M]; std::queue<int>Q; int in[M]; void find_w(int x){ vis[x]=k; for(int i=star[x];i;i=q[i].next){ int now=color[q[i].to]; dis[q[i].to]=std::min(dis[q[i].to],dis[x]+q[i].w); qu[now].push((QAQ){dis[q[i].to],q[i].to}); if(!--in[now]) Q.push(now); } for(int i=first[x];i;i=e[i].next)if(!mark[i]){ int now=e[i].to; if(vis[now]!=k) find_w(now); } } int main(){ fread(buf,1,sizeof(buf),stdin); int x,y,w; n=read(); nr=read(); np=read(); S=read(); for(int i=1;i<=nr;i++) x=read(),y=read(),w=read(),insert(x,y,w); for(int i=1;i<=n;i++)if(!color[i]) hc++,wh[hc]=i,dfs(i); for(int i=1;i<=np;i++) x=read(),y=read(),w=read(),ins(x,y,w),mark[cnt]=1,insq(x,y,w); memset(dis,0x3f,sizeof(dis)); dis[S]=0; for(int i=1;i<=sum;i++) if(f[color[q[i].from]]&&f[color[q[i].to]]) in[color[q[i].to]]++; Q.push(color[S]); qu[color[S]].push((QAQ){0,S}); while(!Q.empty()){ int x=Q.front(); Q.pop(); k++; while(!qu[x].empty()){ QAQ p=qu[x].top(); qu[x].pop(); if(dis[p.id]<p.d) continue; for(int i=first[p.id];i;i=e[i].next)if(!mark[i]){ int now=e[i].to; if(dis[now]>dis[p.id]+e[i].w) dis[now]=dis[p.id]+e[i].w,qu[x].push((QAQ){dis[now],now}); } } find_w(wh[x]); } for(int i=1;i<=n;i++) if(dis[i]>=inf) printf("NO PATH "); else printf("%d ",dis[i]); return 0; }
bzoj 1774: [Usaco2009 Dec]Toll 过路费——(改)floyd
#include<cstdio> #include<cstring> #include<algorithm> using std::min; using std::max; const int M=357; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,map[M][M],h[M],ans[M][M]; struct node{int id,h;}q[M]; bool cmp(node a,node b){return a.h<b.h;} void floyd(){ memset(ans,0x3f,sizeof(ans)); std::sort(q+1,q+1+n,cmp); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ map[i][j]=min(map[i][j],map[i][q[k].id]+map[q[k].id][j]); ans[i][j]=min(ans[i][j],map[i][j]+max(max(h[i],h[j]),q[k].h)); } } int main(){ int x,y,w; n=read(); m=read(); k=read(); memset(map,0x3f,sizeof(map)); for(int i=1;i<=n;i++) h[i]=q[i].h=read(),q[i].id=i; for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),map[x][y]=map[y][x]=min(map[x][y],w); floyd(); for(int i=1;i<=k;i++) x=read(),y=read(),printf("%d ",ans[x][y]); return 0; }
bzoj 1575: [Usaco2009 Jan]气象牛Baric——dp
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using std::min; const int M=107,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,f[M][M]; int v[M],star[M],mid[M][M],last[M]; int main(){ n=read(); k=read(); for(int i=1;i<=n;i++) v[i]=read(); for(int i=1;i<=n;i++){ for(int j=1;j<i;j++) star[i]+=2*abs(v[i]-v[j]); for(int j=i+1;j<=n;j++) last[i]+=2*abs(v[i]-v[j]); for(int j=i+1;j<=n;j++) for(int k=i+1;k<j;k++) mid[i][j]+=abs(2*v[k]-v[i]-v[j]); } memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++){ f[i][1]=star[i]; for(int j=2;j<=i;j++) for(int k=j-1;k<i;k++) f[i][j]=min(f[i][j],f[k][j-1]+mid[k][i]); } int ansh=inf,ans=inf; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) if(f[i][j]+last[i]<=k){ if(ansh>j) ansh=j,ans=f[i][j]+last[i]; else if(j==ansh) ans=min(ans,f[i][j]+last[i]); } printf("%d %d ",ansh,ans); return 0; }
bzoj 1783: [Usaco2010 Jan]Taking Turns——博弈dp
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int M=750007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,id; LL f[M],g[M],v[M]; int main(){ n=read(); id=n+1; for(int i=1;i<=n;i++) v[i]=read(); for(int i=n;i>=1;i--){ f[i]=g[id]+v[i]; g[i]=f[id]; if(f[i]>=f[id]) id=i; } printf("%lld %lld ",f[id],g[id]); return 0; }
bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——大根堆+小根堆+贪心
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> const int M=3e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int f[2*M],cnt,cost,k,n,c,ans; struct pos{ int id,h,ed; bool operator <(const pos &x)const{return x.ed<ed;} }; std::vector<pos>e[M]; std::priority_queue<pos>q1; struct Q{ int id,h,ed; bool operator <(const Q &x)const{return x.ed>ed;} }; std::priority_queue<Q>q2; int main(){ int v,x,y; k=read(); n=read(); c=read(); for(int i=1;i<=k;i++) x=read(),y=read(),v=read(),e[x].push_back((pos){++cnt,v,y}); for(int i=1;i<=n;i++){ while(!q1.empty()){ pos x=q1.top(); if(x.ed>i) break; q1.pop(); if(f[x.id]) continue; f[x.id]=1; cost-=x.h; ans+=x.h; } int mx=e[i].size(); for(int j=0;j<mx;j++){ q1.push((pos){e[i][j].id,e[i][j].h,e[i][j].ed}); q2.push((Q){e[i][j].id,e[i][j].h,e[i][j].ed}); cost+=e[i][j].h; } while(cost>c){ Q x=q2.top(); q2.pop(); if(f[x.id]) continue; f[x.id]=1; if(cost-c>=x.h){cost-=x.h; continue;} int now=cost-c; cnt++; q1.push((pos){cnt,x.h-now,x.ed}); q2.push((Q){cnt,x.h-now,x.ed}); cost=c; } } printf("%d ",ans); return 0; }
bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using std::sort; const int M=2e5+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n; struct pos{int x,y,wh; double k;}q[M]; bool cmp(pos a,pos b){return a.wh!=b.wh?a.wh<b.wh:a.k>b.k;} int main(){ int x,y; n=read(); for(int i=1;i<=n;i++){ x=read(); y=read(); q[i].x=x; q[i].y=y; if(x) q[i].k=1.0*y/x; else q[i].k=-inf; if(x>0&&y>=0) q[i].wh=1; else if(x>=0&&y<0) q[i].wh=2; else if(x<0&&y<=0) q[i].wh=3; else q[i].wh=4; } LL ans=1LL*n*(n-1)*(n-2)/6; sort(q+1,q+1+n,cmp); LL sum=1,ly=2; for(int i=1;i<=n;i++){ sum--; while(1LL*q[ly].y*q[i].x<1LL*q[i].y*q[ly].x){ ly++; sum++; if(ly>n) ly-=n; } ans=ans-sum*(sum-1)/2; } printf("%lld ",ans); return 0; }
bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍——中位数排序
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> using std::sort; using std::min; const int M=2e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,sum,n,x[M],y[M]; struct pos{ int x,y; bool operator <(const pos& h)const{return h.x!=x?h.x<x:h.y<y;} }q[M]; std::map<pos,bool>vis; int main(){ n=read(); for(int i=1;i<=n;i++){ x[i]=read(); y[i]=read(); q[i].x=x[i]; q[i].y=y[i]; } sort(x+1,x+1+n); sort(y+1,y+1+n); int x1=x[(n+1)/2],y1=y[(n+2)/2],x2=x[(n+2)/2],y2=y[(n+1)/2]; if(x1==x2&&y1==y2){ bool f=false; for(int i=1;i<=n;i++)if(q[i].x==x1&&q[i].y==y1){f=true; break;} if(!f){ ans=1; for(int i=1;i<=n;i++){ sum=sum+abs(q[i].x-x1); sum=sum+abs(q[i].y-y1); } } else{ int nx=x1,ny=y1-1; for(int i=1;i<=n;i++){ sum=sum+abs(q[i].x-nx); sum=sum+abs(q[i].y-ny); } ans=1; nx=x1; ny=y1+1; int now=0; for(int i=1;i<=n;i++){ now=now+abs(q[i].x-nx); now=now+abs(q[i].y-ny); } if(sum>now) ans=1; if(sum==now) ans++; nx=x1+1; ny=y1; now=0; for(int i=1;i<=n;i++){ now=now+abs(q[i].x-nx); now=now+abs(q[i].y-ny); } if(sum>now) ans=1; if(sum==now) ans++; now=0; nx=x1-1; ny=y1; for(int i=1;i<=n;i++){ now=now+abs(q[i].x-nx); now=now+abs(q[i].y-ny); } if(sum>now) ans=1; if(sum==now) ans++; } printf("%d %d ",sum,ans); } else{ ans=(x2-x1+1)*(y1-y2+1); for(int i=1;i<=n;i++){ if(q[i].x>=x1&&q[i].x<=x2&&q[i].y>=y2&&q[i].y<=y1){ if(!vis[(pos){q[i].x,q[i].y}]){ans--; vis[(pos){q[i].x,q[i].y}]=1;} } sum=sum+abs(q[i].x-x1); sum=sum+abs(q[i].y-y1); } printf("%d %d ",sum,ans); } return 0; }
bzoj 1590: [Usaco2008 Dec]Secret Message 秘密信息
1. 排序版本 如果A是B的前缀 那么字典序 A<=B<=Ainf 正反做一次就可以了 就是有点慢=_=
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using std::sort; using std::lower_bound; using std::upper_bound; const int M=50007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k; int ans[M],f[M]; struct pos{ int id; std::vector<int>s; bool operator <(const pos& x)const{return s<x.s;} }s1[M],s2[M]; int main(){ n=read(); m=read(); for(int i=1;i<=n;i++){ k=read(); for(int j=1;j<=k;j++) s1[i].s.push_back(read()),s1[i].id=i; } for(int i=1;i<=m;i++){ k=read(); for(int j=1;j<=k;j++) s2[i].s.push_back(read()),s2[i].id=i; } sort(s1+1,s1+1+n); sort(s2+1,s2+1+m); for(int i=1;i<=n;i++){ int lx=lower_bound(s2+1,s2+1+m,s1[i])-s2; s1[i].s.push_back(inf); int rx=upper_bound(s2+1,s2+1+m,s1[i])-s2; s1[i].s.pop_back(); f[lx]++; f[rx]--; } for(int i=1;i<=m;i++){ int lx=upper_bound(s1+1,s1+1+n,s2[i])-s1; s2[i].s.push_back(inf); int rx=upper_bound(s1+1,s1+1+n,s2[i])-s1; s2[i].s.pop_back(); ans[s2[i].id]=rx-lx; } int now=0; for(int i=1;i<=m;i++){now+=f[i]; ans[s2[i].id]+=now;} for(int i=1;i<=m;i++) printf("%d ",ans[i]); return 0; }
2. trie版本 记一下每个位置作为多少个串的前缀 以及每个串的终止位置 统计一波就可以了 很快QAQ
#include<cstdio> #include<cstring> #include<algorithm> const int M=1e6+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,son[M],sum[M],ans[M]; int s[M],c[M][2],cnt; void insert(int len){ int rt=0; for(int i=1;i<=len;i++){ if(!c[rt][s[i]]) c[rt][s[i]]=++cnt; rt=c[rt][s[i]]; son[rt]++; } sum[rt]++; } int find(int len){ int rt=0,ans=0; for(int i=1;i<=len;i++){ if(!c[rt][s[i]]) break; rt=c[rt][s[i]]; if(i==len) ans+=son[rt]; else ans+=sum[rt]; } return ans; } int main(){ n=read(); m=read(); for(int i=1;i<=n;i++){ k=read(); for(int j=1;j<=k;j++) s[j]=read(); insert(k); } for(int i=1;i<=m;i++){ k=read(); for(int j=1;j<=k;j++) s[j]=read(); printf("%d ",find(k)); } return 0; }
bzoj 3940: [Usaco2015 Feb]Censoring——another坑QAQ
bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操——二分+树形dp+贪心
#include<cstdio> #include<cstring> #include<algorithm> using std::sort; const int M=2e5+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,sz[M]; int first[M],cnt,s[M]; struct node{int to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} bool cmp(int x,int y){return x>y;} int ans,mx; void dfs(int x,int fa){ sz[x]=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; dfs(now,x); } cnt=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==fa) continue; s[++cnt]=sz[now]+1; } sort(s+1,s+1+cnt,cmp); int k=1; s[cnt+1]=s[cnt+2]=s[cnt+3]=0; while(s[k]+s[k+1]>mx) ans++,k++; sz[x]=s[k]; } bool check(int ly){ mx=ly; ans=0; dfs(1,-1); return ans<=k; } int main(){ int x,y; n=read(); k=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); int l=1,r=n; while(l<r){ int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; }printf("%d ",l); return 0; }
bzoj 1693: [Usaco2007 Demo]Asteroids——二分图匹配
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using std::min; const int M=2e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k,cur[M],d[M]; int S,T,ans; int first[M],cnt=1; struct node{int to,next,flow;}e[20*M]; void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;} void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);} std::queue<int>q; int bfs(){ memset(d,-1,sizeof(d)); d[S]=1; q.push(S); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||a==0) return a; int flow=0,f; for(int& i=cur[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==d[x]+1&&(f=dfs(now,min(e[i].flow,a)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } int main(){ int x,y; n=read(); k=read(); S=0; T=2*n+1; for(int i=1;i<=n;i++) insert(S,i,1); for(int i=1;i<=n;i++) insert(i+n,T,1); for(int i=1;i<=k;i++) x=read(),y=read(),insert(x,y+n,1); while(bfs()){for(int i=S;i<=T;i++) cur[i]=first[i]; ans+=dfs(S,inf);} printf("%d ",ans); return 0; }
bzoj 1663: [Usaco2006 Open]赶集——dp
#include<cstdio> #include<cstring> #include<algorithm> using std::sort; using std::max; const int M=1e3+7,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,n,ly[M][M],f[M]; struct pos{int h,id;}q[M]; bool cmp(pos a,pos b){return a.h<b.h;} int main(){ n=read(); for(int i=1;i<=n;i++) q[i].h=read(),q[i].id=i; sort(q+1,q+1+n,cmp); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ly[i][j]=read(); for(int i=1;i<=n;i++){ if(ly[1][q[i].id]<=q[i].h) f[i]=1; else f[i]=-inf; for(int j=1;j<i;j++) if(q[j].h+ly[q[j].id][q[i].id]<=q[i].h) f[i]=max(f[i],f[j]+1); } for(int i=1;i<=n;i++) ans=max(ans,f[i]); printf("%d ",ans); return 0; }
bzoj 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草——一类dp问题QAQ
#include<cstdio> #include<cstring> #include<algorithm> using std::min; using std::sort; const int M=1e3+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,star; int f1[M][M],f2[M][M],s[M]; int main(){ n=read(); star=read(); for(int i=1;i<=n;i++) s[i]=read(); sort(s+1,s+1+n); for(int i=1;i<=n;i++) f1[i][i]=f2[i][i]=n*abs(star-s[i]); for(int len=2;len<=n;len++){ for(int i=1;i<=n-len+1;i++){ int j=i+len-1,now=n-j+i; f1[i][j]=min(f1[i+1][j]+(s[i+1]-s[i])*now,f2[i+1][j]+(s[j]-s[i])*now); f2[i][j]=min(f1[i][j-1]+(s[j]-s[i])*now,f2[i][j-1]+(s[j]-s[j-1])*now); } }printf("%d ",min(f1[1][n],f2[1][n])); return 0; }
bzoj 1594: [Usaco2008 Jan]猜数游戏——二分+线段树
#include<cstdio> #include<cstring> #include<algorithm> using std::sort; using std::max; using std::min; const int M=1e5+7,N=3e6+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int cnt,n,m,lx[M],rx[M],mn[N],sign[N],ll[M],rr[M]; struct pos{int l,r,v;}q[M],s[M]; bool cmp(pos a,pos b){return a.v>b.v;} void clear(){ cnt=1; memset(mn,0,sizeof(mn)); memset(sign,0,sizeof(sign)); } int L,R; void up(int x){mn[x]=min(mn[x<<1],mn[x<<1^1]);} void down(int x){ if(!sign[x]) return ; int ls=x<<1,rs=x<<1^1; sign[x]=0; sign[ls]=sign[rs]=1; mn[ls]=mn[rs]=1; } void modify(int x,int l,int r){ if(L<=l&&r<=R){ mn[x]=1; sign[x]=1; return ; } down(x); int mid=(l+r)>>1; if(L<=mid) modify(x<<1,l,mid); if(R>mid) modify(x<<1^1,mid+1,r); up(x); } int push_mn(int x,int l,int r){ if(L<=l&&r<=R) return mn[x]; down(x); int mid=(l+r)>>1,ans=1; if(L<=mid) ans=min(ans,push_mn(x<<1,l,mid)); if(R>mid) ans=min(ans,push_mn(x<<1^1,mid+1,r)); return ans; } bool check(int k){ if(!k) return 1; clear(); for(int i=1;i<=k;i++) s[i]=q[i]; sort(s+1,s+1+k,cmp); int color=s[1].v; lx[1]=s[1].l; rx[1]=s[1].r; ll[1]=lx[cnt],rr[1]=rx[cnt]; for(int i=2;i<=k;i++){ if(s[i].v!=color){ cnt++; color=s[i].v; lx[cnt]=s[i].l; rx[cnt]=s[i].r; ll[cnt]=lx[cnt]; rr[cnt]=rx[cnt]; } else lx[cnt]=min(lx[cnt],s[i].l),rx[cnt]=max(rx[cnt],s[i].r),ll[cnt]=max(ll[cnt],s[i].l),rr[cnt]=min(rr[cnt],s[i].r); if(ll[cnt]>rr[cnt]) return 1; } for(int i=1;i<=cnt;i++){ L=ll[i]; R=rr[i]; if(push_mn(1,1,n)!=0) return 1; L=lx[i]; R=rx[i]; modify(1,1,n); } return 0; } int main(){ n=read(); m=read(); for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].v=read(); int l=1,r=m+1; while(l<r){ int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } if(r>m) printf("0 "); else printf("%d ",r); return 0; }
bzoj 1583: [Usaco2009 Mar]Moon Mooing 哞哞叫
因为两个函数都是单增的所以维护队列就可以了
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int M=4e6+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL num[15][15],c,n; LL ans[M],cnt,l=1,r=1; int main(){ c=read(); n=read(); for(int i=1;i<=2;i++) for(int j=1;j<=3;j++) num[i][j]=read(); ans[++cnt]=c; LL n1=c*num[1][1]/num[1][3]+num[1][2]; LL n2=c*num[2][1]/num[2][3]+num[2][2]; while(cnt<n){ if(n1<n2){ if(n1!=ans[cnt]) ans[++cnt]=n1; n1=ans[++l]*num[1][1]/num[1][3]+num[1][2]; } else{ if(n2!=ans[cnt]) ans[++cnt]=n2; n2=ans[++r]*num[2][1]/num[2][3]+num[2][2]; } }printf("%lld ",ans[cnt]); return 0; }
bzoj 1716: [Usaco2006 Dec]The Fewest Coins 找零钱——多重背包+完全背包
#include<cstdio> #include<cstring> #include<algorithm> using std::max; using std::min; const int M=157,N=30007,inf=0x3f3f3f3f; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,n,T,m,q[N],id[N],ql,qr,mx; int v[M],c[M],f[N],ly[N]; int main(){ //freopen("qwq.out","w",stdout); n=read(); T=read(); for(int i=1;i<=n;i++) v[i]=read(),mx=max(mx,v[i]); for(int i=1;i<=n;i++) c[i]=read(); m=mx*mx+T; for(int i=1;i<=m;i++) f[i]=ly[i]=inf; for(int i=1;i<=n;i++){ for(int j=0;j<v[i];j++){ ql=1; qr=0; for(int k=0,now;(now=k*v[i]+j)<m;k++){ int h=f[now]-k; while(ql<=qr&&q[qr]>=h) qr--; while(ql<=qr&&id[ql]<k-c[i]) ql++; q[++qr]=h; id[qr]=k; f[now]=min(inf,q[ql]+k); } } } for(int i=1;i<=n;i++) for(int j=v[i];j<=m;j++) ly[j]=min(ly[j],ly[j-v[i]]+1); ans=inf; for(int i=T;i<=m;i++) ans=min(ans,f[i]+ly[i-T]); printf("%d ",ans==inf?-1:ans); return 0; }
bzoj 1775: [Usaco2009 Dec]Vidgame 电视游戏问题——dp
#include<cstdio> #include<cstring> #include<algorithm> using std::max; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,p[55],k,c[55],w[55]; int f[55][100007]; int main(){ n=read(); m=read(); for(int i=1;i<=n;i++){ p[i]=read(); k=read(); for(int j=1;j<=k;j++){ c[j]=read(); w[j]=read(); for(int s=m;s>=c[j];s--) f[i][s]=max(f[i][s],max(f[i-1][s-c[j]]+w[j],f[i][s-c[j]]+w[j])); } for(int j=m;j>=p[i];j--) f[i][j]=max(f[i-1][j],f[i][j-p[i]]); for(int j=0;j<=p[i]-1;j++) f[i][j]=f[i-1][j]; } int ans=0; for(int i=0;i<=n;i++) ans=max(ans,f[i][m]); printf("%d ",ans); return 0; }
bzoj 1712: [Usaco2007 China]Summing Sums 加密——矩阵乘法
这道题我们可以发现和(sum)每次都会乘(n-1) 所以单独考虑每一位就可以了 这样复杂度就可以接受了
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int M=5e4+7,mod=98765431; LL read(){ LL ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL sum,n,m,v[M]; LL ans[3][3],b[3][3],c[3][3]; void pmod(LL a[3][3],LL b[3][3]){ memset(c,0,sizeof(c)); for(int i=1;i<=2;i++) for(int k=1;k<=2;k++) for(int j=1;j<=2;j++) c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod+mod)%mod; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) a[i][j]=c[i][j]; } int main(){ n=read(); m=read(); for(int i=1;i<=n;i++) v[i]=read(),sum=(sum+v[i])%mod; ans[1][1]=ans[2][2]=1; b[1][1]=-1; b[1][2]=1; b[2][1]=0; b[2][2]=n-1; while(m){ if(m&1) pmod(ans,b); pmod(b,b); m>>=1; } sum=(ans[1][2]*sum)%mod; for(int i=1;i<=n;i++) printf("%lld ",((ans[1][1]*v[i])%mod+sum+mod)%mod); return 0; }
bzoj 1916: [Usaco2010 Open]冲浪——dp
f[i][j]表示到点i失控j次的答案 注意按拓扑序来 从n到1逆着dp就可以了QAQ 拓扑的时候小心点 为此WA了3次QAQ
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using std::max; using std::min; using std::queue; const int M=250000,N=100007; const LL inf=1e18; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,k,vis[N]; LL f[N][15]; int first[N],cnt,in[N]; struct node{int to,next; LL w;}e[2*M]; void ins(int a,int b,LL w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);} queue<int>q; void topsort(int x){ for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(vis[now]) continue; if(!--in[now]) q.push(now),vis[now]=1; } } void solve(){ int x=q.front(); q.pop(); if(x==n){for(int i=1;i<=k;i++) f[x][i]=-inf; topsort(x); return ;} LL mn=inf,mx=-inf; for(int j=0;j<=k;j++){ for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(!vis[now]) continue; if(f[now][j]>=0) mx=max(mx,f[now][j]+e[i].w); if(j&&f[now][j-1]>=0) mn=min(mn,f[now][j-1]+e[i].w); } f[x][j]=mx<0?(mn<0?-inf:mn):(mn<0?mx:min(mx,mn)); } topsort(x); } int main(){ int x,y,w; n=read(); m=read(); k=read(); for(int i=1;i<=m;i++){ x=read(); y=read(); w=read(); insert(x,y,w); in[x]++; } for(int i=1;i<=n;i++)if(!in[i]) q.push(i),vis[i]=1; while(!q.empty()) solve(); printf("%lld ",f[1][k]); return 0; }
bzoj 2274: [Usaco2011 Feb]Generic Cow Protests——树状数组优化dp
f[i]表示前i个数的方案数 这题本质上就是
这里只要满足前缀和小于i的f[j]就可以辣 这个离散化一下前缀和然后树状数组维护一下就可以辣
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using std::sort; using std::unique; using std::lower_bound; const int M=2e5+7,mod=1e9+9; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,s[M]; LL b[M],c[M],cnt; #define lowbit(x) x&-x void insert(int x,LL w){ while(x<=cnt){ s[x]=(s[x]+w)%mod; x+=lowbit(x); } } LL query(int x){ LL sum=0; while(x) sum=(sum+s[x])%mod,x-=lowbit(x); return sum; } int main(){ n=read(); for(int i=1;i<=n;i++) b[i]=b[i-1]+read(),c[++cnt]=b[i]; cnt++; sort(c+1,c+1+cnt); cnt=unique(c+1,c+1+cnt)-c-1; for(int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+1+cnt,b[i])-c; LL ans=lower_bound(c+1,c+1+cnt,0)-c; insert(ans,1); for(int i=1;i<=n;i++) ans=query(b[i]),insert(b[i],ans); printf("%lld ",ans); return 0; }
bzoj 3408: [Usaco2009 Oct]Heat Wave 热浪——最短路
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> const int M=1e4+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,S,T,d[M]; int first[M],cnt; struct node{int to,next,w;}e[2*M]; void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;} void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);} struct pos{ int id,d; bool operator <(const pos& x)const{return x.d<d;} }; std::priority_queue<pos>q; void dj(){ memset(d,0x3f,sizeof(d)); d[S]=0; q.push((pos){S,d[S]}); while(!q.empty()){ pos x=q.top(); q.pop(); if(x.d!=d[x.id]) continue; for(int i=first[x.id];i;i=e[i].next){ int now=e[i].to; if(d[now]>d[x.id]+e[i].w) d[now]=d[x.id]+e[i].w,q.push((pos){now,d[now]}); } } } int main(){ int x,y,w; n=read(); m=read(); S=read(); T=read(); for(int i=1;i<=m;i++) x=read(),y=read(),w=read(),insert(x,y,w); dj();printf("%d ",d[T]); return 0; }
bzoj 2274: [Usaco2011 Feb]Generic Cow Protests——树状数组优化dp
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int M=2e5+7,mod=1e9+9; using std::sort; using std::lower_bound; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,v[M],x[M],f[M],s[M]; #define lowbit(x) x&-x void ins(int x,int v){while(x<=n) s[x]=(s[x]+v)%mod,x+=lowbit(x);} int query(int x){int sum=0; while(x) sum=(sum+s[x])%mod,x-=lowbit(x); return sum;} int main(){ n=read(); for(int i=1;i<=n;i++){ v[i]=v[i-1]+read(); x[i]=v[i]; if(v[i]>=0) f[i]=1; } sort(x+1,x+1+n); for(int i=1;i<=n;i++) v[i]=lower_bound(x+1,x+1+n,v[i])-x; for(int i=1;i<=n;i++){ f[i]=(f[i]+query(v[i]))%mod; ins(v[i],f[i]); }printf("%d ",f[n]); return 0; }
bzoj 1740: [Usaco2005 mar]Yogurt factory 奶酪工厂——贪心
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const LL inf=1e15; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,s,k,mn=inf,ans; int main(){ n=read(); s=read(); for(int i=1;i<=n;i++){ k=read(); if(k-s*i<mn) mn=k-s*i; k=read(); ans=ans+(mn+s*i)*k; }printf("%lld ",ans); return 0; }
bzoj 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛——二分答案+网络流
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define LL long long using std::min; using std::max; const int M=557,Max=0x3f3f3f3f; const LL inf=1e15; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m,S,T; LL tot,s[M][M],c[M],h[M],l,r; int first[5*M],cnt,cur[5*M]; struct node{int to,next,flow;}e[M*M*2]; void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;} void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);} std::queue<int>q; LL d[5*M]; int bfs(){ memset(d,-1,sizeof(d)); d[S]=0; q.push(S); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now); } } return d[T]!=-1; } int dfs(int x,int a){ if(x==T||!a) return a; int f,flow=0; for(int &i=cur[x];i;i=e[i].next){ int now=e[i].to; if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){ e[i].flow-=f; e[i^1].flow+=f; flow+=f; a-=f; if(!a) break; } } return flow; } bool check(LL k){ S=0; T=2*n+1; cnt=1; memset(first,0,sizeof(first)); for(int i=1;i<=n;i++) insert(S,i,c[i]),insert(i+n,T,h[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)if(s[i][j]<=k) insert(i,j+n,Max); LL sum=0; while(bfs()){ for(int i=0;i<=T;i++) cur[i]=first[i]; sum+=dfs(S,Max); } return sum>=tot; } int main(){ int x,y,w; n=read(); m=read(); for(int i=1;i<=n;i++) c[i]=read(),h[i]=read(),tot+=c[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)if(i!=j) s[i][j]=inf; for(int i=1;i<=m;i++){ x=read(); y=read(); w=read(); s[x][y]=s[y][x]=min(s[x][y],1LL*w); } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) s[i][j]=min(s[i][j],s[i][k]+s[k][j]); r=1e15; while(l<r){ LL mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } if(r==1e15) puts("-1"); else printf("%lld ",r); return 0; }