这题的标解在年鉴上面有。。
然而完全看不懂。。
甚至觉得有一点问题。。
于是我尝试地贪心了一天QAQ
最终WA收场。。
实在贪不动了。。
CODEVS上面拿了70分,还算可以吧。。
70分的贪心CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int N=1005;
int s[N];
int n;
int ans=(1<<30);
int mymin (int x,int y){return x<y?x:y;}
int a[N],b[N];//把两个杆拿出来 从上往下放吧
int a_tot,b_tot;
int next[N];//下一个在哪里
bool better (int x)//第x位往后是否更优
{
int tot=0;
bool tf=false;
for (int u=x+1;u<next[x];u++)
{
if (s[u]==1)
{
tot++;
tf=true;
}
else
if (tf)
tot--;
}
return tot<1;
}
void solve (int x)//先完成哪一个
{
int lalal=0;//有多少个这个东西
int Next=-1;
int sum=0;//现在已经走了多少步了
for (int u=n;u>=1;u--)
{
if(s[u]==x)
{
sum++;
next[u]=Next;
Next=u;
}
}
int u;
next[0]=Next;
int c[N],tot=0;//那一根棍子的东西
bool tf=false;//是否已经出现了不合法
for (u=0;next[u]!=-1;u=next[u])
{
if (tf==false)
{
if (better(u))
{
for (int i=u+1;i<next[u];i++)
if (s[i]!=1)
{
sum++;
}
for (int i=u+1;i<next[u];i++)
if (s[i]==1)
{
sum=sum+2;
c[++tot]=s[i];
}
}
else tf=true;
}
if (tf==true)
{
for (int i=u+1;i<next[u];i++)
{
c[++tot]=s[i];
sum++;
}
}
for (int i=u+1;i<next[u];i++)
if (s[i]==1)
tf=true;
}
/*现在是到第i根*/
u++;
a_tot=0,b_tot=0;
for (int i=u;i<=n;i++) a[++a_tot]=s[i];
for (int i=tot;i>=1;i--) b[++b_tot]=c[i];
/* printf("%d\n",sum);
for (int i=1;i<=a_tot;i++) printf("%d ",a[i]);
printf("\n");
for (int i=1;i<=b_tot;i++) printf("%d ",b[i]);
printf("\n");*/
while (a_tot>0&&a[a_tot]==1)
a_tot--;
while (b_tot>0&&b[b_tot]!=1)
b_tot--;
int k1=0,k2=0;
for (int i=a_tot;i>=1;i--)
{
if (a[i]==1)
break;
k1++;
}
for (int i=b_tot;i>=1;i--)
{
if (b[i]!=1)
break;
k2++;
}
int k3=0,k4=0;
for (int u=1;u<=a_tot;u++)
{
if (a[u]==1) break;
k3++;
}
for (int u=1;u<=b_tot;u++)
{
if (b[u]!=1) break;
k4++;
}
ans=min(ans,sum+k1+k2+min(k1,k2)+2*(a_tot-k1)+2*(b_tot-k2));//第一种贪心策略
/*第二种贪心策略*/
lalal=0;
for (int i=1;i<=b_tot;i++)
{
if (b[i]==1) lalal++;
else lalal=lalal+2;
}
ans=min(ans,sum+lalal+a_tot*2);
/*第三种贪心策略*/
lalal=0;
for (int i=1;i<=a_tot;i++)
{
if (a[i]==1) lalal=lalal+2;
else lalal++;
}
ans=min(ans,sum+lalal+b_tot*2);
}
int main()
{
scanf("%d",&n);
for (int u=1;u<=n;u++)
scanf("%d",&s[u]);
solve(2);
solve(3);
printf("%d\n",ans);
return 0;
}