您的位置:首页 > 其它

SRM 551 Div1

2016-11-22 14:42 309 查看
noip d2t3 没清数组实力滚粗,赶紧做一波SRM 冷静一下。。。。

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: