CF301Div2ProB
convex 凸
convave 凹
omit 省略
emit 发射,HMM发射概率
太久没写算法,Partition算法都不会写了 T_T
掌握Partition的要诀就是一点,记忆!
双向扫描版的,最后要把a[low], a[i] swap。我记忆为单向扫描了。
明天就毕业答辩了,感觉硕士三年也走到头了。
是该面对社会了
http://codeforces.com/contest/540/problem/B
这道题目,是构造型算法的贪心。
给定k个数,构造剩余的n-k个数,使得n-k个数都在[1, p],并且数组sum<=x, 并且median>=y
题解是对于剩下数,构造y,使得中位数足够,然后剩下的数都是1,也就是尽可能小,因为sum要<=x, 尽可能小,这种是尽可能小,median不用至少要这么多y才行。
因为y增加的话median一定是增长的,如果前面可以的话,后面一定可以。
int main()
{
/*
#ifndef ONLINE_JUDGE
freopen ("in.txt" , "r" , stdin);
freopen ("out.txt" , "w" , stdout);
#endif
*/
int p ,x, y, n, k;
while(cin>>n>>k>>p>>x>>y)
{
fill_n(a, n, 1);
int cnt=0;
for(int i=0;i<k;i++)
{
cin>>a[i];
if(a[i]>=y) cnt++;
}
//int i;
for(int i=k;i<n;i++)
{
if(cnt>=(n+1)/2) break;
a[i]=y;
cnt++;
}
//if(i==n) {puts("-1"); continue;}
int sum=0;
for(int i=0;i<n;i++) sum+=a[i];
if(sum<=x && cnt>=(n+1)/2)
{
for(int i=k;i<n;i++) cout<<a[i]<<" ";
cout<<endl;
}
else puts("-1");
}
return 0;
}
附上炮哥的一个构造算法,先满足尽可能接近sum,然后再判断中位数是否是y符合的。
int main()
{
/*
#ifndef ONLINE_JUDGE
freopen ("in.txt" , "r" , stdin);
freopen ("out.txt" , "w" , stdout);
#endif
*/
int p ,x, y, n, k;
while(cin>>n>>k>>p>>x>>y)
{
fill_n(a, n, 1);
for(int i=0;i<k;i++) cin>>a[i];
int sum=0;
for(int i=0;i<n;i++) sum+=a[i];
for(int i=k;i<n;i++)
{
if(sum+y-1>x) break;
a[i]=y;
sum+=y-1;
}
for(int i=0;i<n;i++) b[i]=a[i];
sort(b, b+n);
if(sum<=x && b[n/2]>=y)
{
for(int i=k;i<n;i++) cout<<a[i]<<" ";
cout<<endl;
}
else puts("-1");
}
return 0;
}
炮哥,去了百度记得带我飞啊~~