百度之星初赛B轮 hdu 6114 6118 6119
hdu 6114
思路:就是在max(n,m)中取min(n,m)个,(模板收好
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int MOD=1e9+7; 5 const int N = 2000 + 5; 6 7 int F[N], Finv[N], inv[N]; 8 void init(){ 9 inv[1] = 1; 10 for(int i = 2; i < N; i ++){ 11 inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; 12 } 13 F[0] = Finv[0] = 1; 14 for(int i = 1; i < N; i ++){ 15 F[i] = F[i-1] * 1ll * i % MOD; 16 Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD; 17 } 18 } 19 int comb(int n, int m){//comb(n, m)就是C(n, m) 20 if(m < 0 || m > n) return 0; 21 return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD; 22 } 23 24 int main(){ 25 int t; 26 init(); 27 scanf("%d",&t); 28 while(t--){ 29 int n,m; 30 scanf("%d%d",&n,&m); 31 printf("%d\n",comb(max(n,m),min(n,m))); 32 } 33 }
hdu 6118
PS:来自大佬的费用流
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e3+100; 5 const int inf=1e9; 6 struct edge 7 { 8 int from,to; 9 int c,w; 10 }; 11 vector<edge>es; 12 vector<int>G[N]; 13 int pre[N]; 14 int dist[N]; 15 void init(int n) 16 { 17 es.clear(); 18 for(int i=0;i<=n+200;i++) G[i].clear(); 19 } 20 void addedge(int u,int v,int c,int w) 21 { 22 es.push_back((edge) 23 { 24 u,v,c,w 25 }); 26 es.push_back((edge) 27 { 28 v,u,0,-w 29 }); 30 int x=es.size(); 31 G[u].push_back(x-2); 32 G[v].push_back(x-1); 33 } 34 35 bool spfa(int s,int t) 36 { 37 queue<int> q; 38 bool inq[N]; 39 for(int i=0; i<N; i++) dist[i]=inf,inq[i]=false; 40 pre[s]=-1; 41 dist[s]=0; 42 q.push(s); 43 while(!q.empty()) 44 { 45 int u=q.front(); 46 q.pop(); 47 inq[u]=false; 48 for(int i=0; i<G[u].size(); i++) 49 { 50 edge e=es[G[u][i]]; 51 if(e.c&&dist[e.to]>dist[u]+e.w) 52 { 53 pre[e.to]=G[u][i]; 54 dist[e.to]=dist[u]+e.w; 55 if(!inq[e.to]) q.push(e.to),inq[e.to]=true; 56 } 57 } 58 } 59 return dist[t]<0; 60 } 61 62 void dinic(int s,int t) 63 { 64 int flow=0,cost=0; 65 while(spfa(s,t)) 66 { 67 int d=inf; 68 for(int i=t; i!=s; i=es[pre[i]].from) 69 d=min(d,es[pre[i]].c); 70 flow+=d; 71 cost+=d*dist[t]; 72 for(int i=t; i!=s; i=es[pre[i]].from) 73 { 74 es[pre[i]].c-=d; 75 es[pre[i]^1].c+=d; 76 } 77 } 78 printf("%d\n",-cost); 79 } 80 int main() 81 { 82 int n,m; 83 while(~scanf("%d%d",&n,&m)) 84 { 85 for(int i=1; i<=n; i++) 86 { 87 int a,b,c,d; 88 scanf("%d%d%d%d",&a,&b,&c,&d); 89 addedge(0,i,b,a); 90 addedge(i,n+1,d,-c); 91 } 92 for(int i=1; i<=m; i++) 93 { 94 int u,v,w; 95 scanf("%d%d%d",&u,&v,&w); 96 if(u==v) continue; 97 addedge(u,v,inf,w); 98 addedge(v,u,inf,w); 99 } 100 dinic(0,n+1); 101 init(n); 102 } 103 return 0; 104 }
hdu 6119
思路:处理好重叠区间,然后以当前这个区间往后跑,跑到不能跑为止,当前跑的需要的sum,那么下个区间就可以用sum-(a[i].l-a[i-1].r-1),然后重后面那个区间跑,k多的情况
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10; 5 6 struct node{ 7 int l,r; 8 }a[N]; 9 bool cmp(node p,node q){ 10 if(p.l==q.l) return p.r<q.r; 11 return p.l<q.l; 12 } 13 struct nn{ 14 int l,r; 15 }b[N]; 16 17 int main(){ 18 int n,k; 19 while(scanf("%d%d",&n,&k)!=EOF){ 20 for(int i=1;i<=n;i++) 21 scanf("%d%d",&a[i].l,&a[i].r); 22 sort(a+1,a+1+n,cmp); 23 int x=0; 24 int Maxr=a[1].r; 25 b[x].l=a[1].l; 26 for(int i=2;i<=n;i++){ 27 if(a[i].l<=Maxr){ 28 Maxr=max(Maxr,a[i].r); 29 } 30 else { 31 32 b[x++].r=Maxr; 33 34 b[x].l=a[i].l; 35 Maxr=a[i].r; 36 } 37 } 38 b[x++].r=Maxr;//得到不重叠的区间 39 int sum=0; 40 int t=0; 41 int ans=0; 42 for(int i=0;i<x;i++) 43 { 44 while(sum<=k&&t<x) 45 { 46 t++; 47 if(t<x) 48 sum+=b[t].l-b[t-1].r-1; 49 } 50 if(sum>k) 51 { 52 ans=max(ans,b[t].l-b[i].l-(sum-k)); 53 sum-=b[i+1].l-b[i].r-1; 54 } 55 else 56 { 57 ans=max(ans,b[x-1].r-b[i].l+k-sum+1);//已经跑到最后一个了 58 } 59 60 } 61 printf("%d\n",ans); 62 } 63 }