C. Mortal Kombat Tower(cf)dp

 原题链接:Problem - 1418C - Codeforces

题目大意: 有一个序列n个数,非0即1,有两个人,一个是你的朋友,一个是你。从左到右,从你的朋友先开始,每个人一次必须选一个或两个数。ta选完你选然后又是ta选...问你朋友最后得到数的最小值。

1.其实就是让你的朋友尽量得到更少的1,得到更多的0;

2.用0表示你朋友,1表示你自己。状态转移:用dp[i][0]表示打的第i个怪,且是你朋友打完的。dp[i][1]表示打的第i个怪,且是你打完的。

2.状态转移方程:

//如果朋友拿这个数,就取a[i - 1]是我最后拿的加上a[i]和a[i - 2]是我最后拿的加上..

dp[i][0] = min(dp[i - 1][1] + a[i], dp[i - 2][1] + a[i - 1] + a[i]); //朋友取的第一个数两个数中的第二个数

dp[i][1] = min(dp[i - 1][0], dp[i - 2][0]);

AC代码: 

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ios ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
typedef pair<int, int> PII;
const double pi = acos(-1.0);
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for (int i = n; i >= (1); --i)
typedef long long ll;
#define sqar(x) ((x)*(x))

const int N = 2e5 + 10;
int dp[N][2]; //第i关的时候分别是朋友取a[i]这个值还是我取这个值时朋友的最小值 0:朋友 1 :我
int a[N];

int main(){
  int n,t;
  cin >> t;
  while(t--){
    cin >> n;
    rep(i, n) cin >> a[i];
    dp[1][0] = a[1]; dp[1][1] = INF; //初始化
    dp[2][0] = a[1] + a[2]; dp[2][1] = a[1]; //dp[i][0]、dp[i][1]都是朋友的最小值,所以dp[2][1]是a[1]而不是a[2]                                                                                                      
    for(int i =3; i <= n; i++){
      dp[i][0] = min(dp[i - 1][1] + a[i], dp[i - 2][1] + a[i - 1] + a[i]); //上一次我选了一个还是两个
      dp[i][1] = min(dp[i - 1][0], dp[i - 2][0]);
    }
    cout << min(dp[n][0], dp[n][1]) << endl;
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值