BZOJ-1802-跳棋

/*
    BZOJ1802
    题意大概是有一长N的数列,其中1代表可以在游戏中无限增加棋子,0代表可以在游戏前添加棋子。
    游戏的原则和跳棋类似,但是增加一点,被跳过的棋子将会消失。
    求游戏前最少要添加多少棋子和在这种情况下游戏中要添加多少棋子。

    仔细分析下这个题大致可以分为两种情况
    1.所有的1相互独立且互不相邻。
        这种情况下,第一问的最少情况为偶数位为0的个数,第二位最少的情况是偶数位为1的个数
    2.存在有连续1的情况
        这种情况下,两个连续的1就可以到达任何一个位置,所以是不需要提前放置棋子的。
        第二问先找到连续区间,对于每个连续区间向左向右判断其最少值
    注意:如果第一和第二位置为1是不能算计第二种情况下的,被这个坑了。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define ULL unsigned long long 
using namespace std;
const int maxn = 2011;
const ULL maxnum = 0xffffffffffffffff;
ULL f[maxn];
int a[maxn];
int flag = 0;
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        if (i>2&&a[i] == 1 && a[i - 1] == 1)
            flag = 1;
    }
    ULL ans = 0;
    if (!flag)
    {

        for (int i = 1; i <= n; i++)
        {
            if (i % 2 == 0 && a[i] == 0)
                ans++;

        }
        cout << ans << endl << (n / 2 - ans) << endl;

    }
    else
    {
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == 1)
                f[i] = 1;
            else
                f[i] = maxnum;
        }
        for (int i = 1; i <= n; i++)
        {
            if (i > 2 && a[i] == 1 && a[i - 1] == 1)
            {
                for (int j = i - 2; j >= 1; j--)
                {
                    if (f[j] > f[j + 1] + f[j + 2])
                        f[j] = f[j + 1] + f[j + 2];

                }
                for (int j = i + 1; j <= n; j++)
                {
                    if (f[j] > f[j - 1] + f[j - 2])
                        f[j] = f[j - 1] + f[j - 2];
                }
            }

        }
        for (int i = 1; i <= n; i++)
        {
            if (i % 2 == 0)
                ans += f[i];
        }
        cout << 0 << endl << ans << endl;
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值