SRM 551 Div1
2016-11-22 14:42
309 查看
noip d2t3 没清数组实力滚粗,赶紧做一波SRM 冷静一下。。。。
就是一个最短路,如果map[i][j]==′Y′那么i到j有一条长度为∑k<jmap[i][k]==′Y′的边,然后跑0到n-1的最短路。
大概看到40左右的数据就要想meet in the middle呀
考虑枚举最终真甜的个数k,然后第一步是求k个甜的水果,甜度和<=最大甜度 的方案数。这个可以用meet in the middle做,复杂度O(2n/2∗n)
然后求最后得到k个真甜的树的个数。可以用矩阵树定理。真甜的和真甜的,真甜的和不甜的,半甜的和不甜的,不甜的和不甜的连无向边。然后跑矩阵树定理。
不过这样跑出来是小于等于k个真甜的树的个数。
用小于k个真甜的所有容斥一下就行了。
250pts
最终答案里至少有一个点没改变位置。因此枚举没改变位置的点,然后把两边和他同色的点移过来的花费排个序,从小到大往里加,直到超过最大花费,更新一下答案。#include <bits/stdc++.h> using namespace std; int n,top,cnt,sum,ans; int st[110]; class ColorfulChocolates { public: int maximumSpread(string s,int m) { n=s.size(); for(int i=0;i<n;i++) { top=0;cnt=0; for(int j=i-1;j>=0;j--) if(s[j]==s[i]) st[++top]=i-j-cnt-1,cnt++; cnt=0; for(int j=i+1;j<n;j++) if(s[j]==s[i]) st[++top]=j-i-cnt-1,cnt++; sort(st+1,st+1+top); sum=0;int j=0; for(j=1;j<=top;j++) { if(sum+st[j]>m)break; sum+=st[j]; } ans=max(ans,j); } return ans; } }cls;
450pts
第一次见到450的题。就是一个最短路,如果map[i][j]==′Y′那么i到j有一条长度为∑k<jmap[i][k]==′Y′的边,然后跑0到n-1的最短路。
#include <bits/stdc++.h> using namespace std; int f[55],inq[55],n,inf; queue<int>q; class ColorfulWolves { public: int getmin(vector<string> s) { n=s.size(); memset(f,0x3f,sizeof(f)); inf=f[0];inq[0]=1;f[0]=0; q.push(0); while(!q.empty()) { int tmp=q.front();q.pop(); int cnt=0;inq[tmp]=0; for(int i=0;i<n;i++) if(s[tmp][i]=='Y') { if(f[tmp]+cnt<f[i]) { f[i]=f[tmp]+cnt; if(!inq[i]) q.push(i),inq[i]=1; } cnt++; } } return f[n-1]==inf ? -1:f[n-1]; } }cls;
1000pts
感觉这题还是挺强的。。。大概看到40左右的数据就要想meet in the middle呀
考虑枚举最终真甜的个数k,然后第一步是求k个甜的水果,甜度和<=最大甜度 的方案数。这个可以用meet in the middle做,复杂度O(2n/2∗n)
然后求最后得到k个真甜的树的个数。可以用矩阵树定理。真甜的和真甜的,真甜的和不甜的,半甜的和不甜的,不甜的和不甜的连无向边。然后跑矩阵树定理。
不过这样跑出来是小于等于k个真甜的树的个数。
用小于k个真甜的所有容斥一下就行了。
#include <bits/stdc++.h> using namespace std; #define ll long long #define mod 1000000007 vector<int>v1[21],v2[21]; int n,m,ans,top; int way[51],mp[51][51],du[51],tree[51],C[51][51],st[51]; int get(int x,int y,int mx) { int ret=0; if(x>n/2||y>n-n/2)return 0; for(int i=0,j=v2[y].size()-1;i<v1[x].size();i++) { while(j>=0&&v2[y][j]+v1[x][i]>mx)j--; ret=(ret+j+1)%mod; } return ret; } void ade(int x,int y) { du[x]++;du[y]++; mp[x][y]=mp[y][x]=mod-1; } int qpow(int x,int y) { int ret=1; while(y) { if(y&1)ret=(ll)ret*x%mod; x=(ll)x*x%mod;y>>=1; } return ret; } int solve(int n) { int cnt=0; for(int i=0;i<n;i++) { int pos=-1; for(int j=i;j<n;j++) if(mp[j][i])pos=j; if(pos==-1)return 0; if(pos!=i)cnt++; for(int j=0;j<n;j++) swap(mp[pos][j],mp[i][j]); for(int j=i+1;j<n;j++) if(mp[j][i]) { int t=(ll)qpow(mp[i][i],mod-2)*mp[j][i]%mod; for(int k=i;k<n;k++) mp[j][k]=(mp[j][k]-(ll)mp[i][k]*t%mod+mod)%mod; } } int ret=1; for(int i=0;i<n;i++) ret=(ll)ret*mp[i][i]%mod; return cnt&1 ? mod-ret:ret; } class SweetFruits { public: int countTrees(vector<int>val,int mx) { n=val.size(); for(int i=0;i<=n;i++)C[i][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; for(int i=0;i<n;i++) if(val[i]!=-1)st[top++]=val[i]; for(int i=0;i<1<<(top/2);i++) { int cnt=0,sum=0; for(int j=0;j<top/2;j++) if(i>>j&1)cnt++,sum+=st[j]; v1[cnt].push_back(sum); } for(int i=0;i<1<<(top-top/2);i++) { int cnt=0,sum=0; for(int j=0;j<(top-top/2);j++) if(i>>j&1)cnt++,sum+=st[j+top/2]; v2[cnt].push_back(sum); } for(int i=0;i<=n/2;i++) sort(v1[i].begin(),v1[i].end()); for(int i=0;i<=n-n/2;i++) sort(v2[i].begin(),v2[i].end()); for(int i=0;i<n;i++) if(val[i]!=-1)m++; for(int i=0;i<=m;i++) { for(int j=0;j<=i;j++) way[i]=(way[i]+get(j,i-j,mx))%mod; memset(mp,0,sizeof(mp)); memset(du,0,sizeof(du)); for(int j=0;j<i;j++) { for(int k=j+1;k<i;k++)ade(j,k); for(int k=m;k<n;k++)ade(j,k); } for(int j=i;j<m;j++) for(int k=m;k<n;k++)ade(j,k); for(int j=m;j<n;j++) for(int k=j+1;k<n;k++)ade(j,k); for(int j=0;j<n;j++)mp[j][j]+=du[j]; tree[i]=solve(n-1); for(int j=0;j<i;j++) tree[i]=(tree[i]-(ll)tree[j]*C[i][j]%mod+mod)%mod; ans=(ans+(ll)tree[i]*way[i]%mod)%mod; } return ans; } }cls;
相关文章推荐
- SRM 551 DIV2
- SRM 551 div2
- SRM 551 div2 950(DP, 环形+优化)
- 【TopCoder SRM 551 Div2】Solutions
- [矩阵树定理 容斥 meet in middle] Topcoder SRM 551 DIV1 Hard. SweetFruits
- TC SRM 551 div2 题解
- [meet in middle 矩阵树定理 容斥原理] SRM 551 div1 SweetFruits
- TopCoder 250 points 4-SRM 145 DIV 2 128.72/250 51.49%
- TopCoder 550 points 1-SRM 144 DIV 1 165/550 30%
- SRM 397 DIV2 [500]
- TopCoder SRM 669 DIV 1
- SRM 670 div2 A B C div1 A(贪心,子问题合并)
- 记第一次TopCoder, 练习SRM 583 div2 250
- SRM 207 Div II Level One: TransportCounting
- SRM 584 Div II Level Two: Egalitarianism,DFS,BFS算法
- srm 144 div 2 550
- SRM 223 Div II Level Two: BlackAndRed,O(N)复杂度
- SRM 577 Div II Level Two: EllysRoomAssignmentsDiv2
- 【TC SRM 718 DIV 2 B】Reconstruct Graph
- 【SRM 717 div2 B】LexmaxReplace