BZOJ 1802: [Ahoi2009]checker
若有两个红格相邻
第一问的答案为0,所有位置上的棋子都可以通过在这两个格子上放棋子得到
第二设f[i]表示想让第i个格子上有棋子需要放的棋子数
若没有,第一问答案为偶数格子上白格的个数,第二问为偶数格子上红格的个数
#include<complex> #include<cstdio> #include<cstring> using namespace std; const int N=1e3+7; int n; bool flag; long long f[N]; bool a[N]; int qread() { int x=0; char ch=getchar(); while(ch<'0' || ch>'9')ch=getchar(); while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) a[i]=qread(); for(int i=3;i<=n;i++) if(a[i]&a[i-1])flag=1; if(!flag) { int b=0,c=0; for(int i=2;i<=n;i+=2) a[i]?c++:b++; printf("%d\n%d\n",b,c); return 0; } memset(f,0x3f,sizeof(f)); f[1]=0; for(int i=2;i<=n;i++) if(a[i])f[i]=1; for(int i=2;i<=n;i++) if(a[i]&a[i+1]) { for(int j=i-1;j>1;j--) f[j]=min(f[j],f[j+1]+f[j+2]); for(int j=i+2;j<=n;j++) f[j]=min(f[j],f[j-1]+f[j-2]); } long long ans=0; for(int i=2;i<=n;i+=2) ans+=f[i]; printf("0\n%lld\n",ans); return 0; }