题目链接:http://codeforces.com/problemset/problem/747/D点击打开链接
我的思路是这样的
将冬天和夏天看成两个相反的颜色(相反数)
在n的区间上进行操作 有点区间涂色的感觉。。
然后就问m次将夏天变成冬天后 区间上的颜色段数最少
然后开始xjb乱搞。。
记录夏天的所有区段
然后从区段最小的开始变成冬天
然后就wa了。。
这个错误的例子有很多 比如
7 5
-1 0 0 0 -1 0 0
很明显 我们应当去连续的3个0而不是取后面的两个0
因为最后是结束状态
处理方法是把他拿出来最后判断
然后又wa
再来个例子。。
7 5
0 0 0 -1 0 0 -1
这个时候 开始状态影响了贪心判断
因此得从出现了第一个冬天之后开始判断
然后
还是wa
开始结束状态在同一个区段内
1 1
1
这个时候稍微改下代码判断条件先后顺序即可
不建议看代码 因为很乱很糟糕
如果能体会这些特殊情况就很不错了
#include <bits/stdc++.h>
using namespace std;
struct xjy
{
int l;
int r;
};
int cmp1(xjy a,xjy b)
{
if((a.r-a.l)==(b.r-b.l))
return a.l<b.l;
return a.r-a.l<b.r-b.l;
}
vector<xjy> re;
vector<int> s;
int main()
{
int n,m;
cin >> n >> m;
for(int i=0;i<n;i++)
{
int mid;
cin >> mid;
s.push_back(mid);
}
int l=0,r=0,flag=0,summer=0,summerflag=0;
for(int i=0;i<n;i++)
{
if(s[i]>=0)
{
if(!flag)
{
l=i;
flag=1;
}
summer++;
}
else
{
if(flag)
{
flag=0;
r=i-1;
xjy mid;
mid.l=l;
mid.r=r;
if(summerflag)
re.push_back(mid);
}
}
if(s[i]<0)
summerflag=1;
}
xjy last;
last.l=1;
last.r=0;
if(flag&&summerflag)
{
flag=0;
r=n-1;
last.l=l;
last.r=r;
}
//for(int i=0;i<re.size();i++)
{
//cout << re[i].l << " " << re[i].r << endl;
}
sort(re.begin(),re.end(),cmp1);
m-=(n-summer);
flag=0;
int cnt=0;
if(m>=0)
flag=1;
while(m>=0)
{
if(cnt<re.size())
{
if(m>=(re[cnt].r-re[cnt].l+1))
{
m-=(re[cnt].r-re[cnt].l+1);
for(int j=re[cnt].l;j<=re[cnt].r;j++)
s[j]=-1;
cnt++;
}
else
break;
}
else
break;
}
//cout << m << endl;
if(m>=(last.r-last.l+1))
{
for(int j=last.l;j<=last.r;j++)
s[j]=-1;
}
//cout << last.l << " " << last.r << endl;
//for(int i=0;i<n;i++)
//cout << s[i] << " " ;
//cout << endl;
int ans=0;
if(!flag)
{
cout << "-1" << endl;
}
else
{
flag=0;
for(int i=0;i<n;i++)
{
if(flag==0&&s[i]<0)
{
flag=1;
ans++;
}
else if(flag==1&&s[i]>=0)
{
flag=0;
ans++;
}
}
cout << ans << endl;
}
}