# 2021年东华大学金马程序设计联赛 K. AEMShana loves games!

K. AEMShana loves games!

题目传送门:

题目传送门!

题面:

在这里插入图片描述

题目大意:

在这里插入图片描述

代码:


#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 1e6 + 10;
const int MAX = 1e5 + 9;
struct Node {
    int t;
    int p;
    int k;
} node[maxn];
int dp[MAX][21];
int dpp[MAX][21];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int n;
    while (cin >> n) {
        memset(dp, 0, sizeof(dp));
        memset(dpp, 0, sizeof(dpp));
        int tt = 0;
       for (int i = 1; i <= n; i++) {
            cin >> node[i].t >> node[i].p >> node[i].k;
            if (tt < node[i].t) tt = node[i].t;
            if (!node[i].k)dp[node[i].t][node[i].p] += 1;
            else dp[node[i].t][node[i].p] -= 1;
            //注意,不是说有黑球就是-1,白球就是1。因为题目上说了球下落不是一个个的,所以还是用+=1/-=1比较靠谱。
            //因为这个点我卡了二十几分钟,感觉dp递推全对的草。
        }
        for (int i = 1; i <= tt; i++) {
            for (int j = 0; j < 11; j++) {
                int tmp = abs(j - 5);
                if (tmp <= i) {
                //这个点可以到达。
                    dpp[i][j] = dpp[i - 1][j];
                    //先继承同一位置上一个时间的值;
                    //dpp[i][j]记录当前位置j,当前时间i的值
                    if (j && abs(j - 1 - 5) <= i) 
                    //满足此条件才可能是上一个时间从j-1位置转换过来的。
                    dpp[i][j] = max(dpp[i][j], dpp[i - 1][j - 1]);
                    //意思是dpp[i][j]可能是之前就在此位置,本回合未移动(dpp[i - 1][j]),或者本回合是上一回合移动后结果(dpp[i - 1][j - 1]),取大的。
                    if (j < 10 && abs(j + 1 - 5) <= i)
                    //道理同上。
                        dpp[i][j] = max(dpp[i][j], dpp[i - 1][j + 1]);
                        
                          dpp[i][j] += dp[i][j];//通过上一时间原地不动、位置+1、位置-1三种情况取值最大后,再加上这个位置的值,因为毕竟这代表第i秒第j位置的值,所以必须要接受这个时刻的球。
                } else dpp[i][j] = -INF;
                //不可达点直接负无穷好吧
            }
        }
        int ans = -INF;
        for (int i = 0; i < 11; i++)
            if (abs(i - 5) <= tt)
            //对可达点进行取MAX
             ans = max(ans, dpp[tt][i]);
        cout << ans << endl;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值