申请添加题解(思路与众不同)
查看原帖
申请添加题解(思路与众不同)
1238782
Hacker641楼主2024/10/27 11:06

思路:贪一下,优先用大数打小数,也就是:

  • 先按照攻击力 rir_i 建桶(升序排序),从小到大第 xxx 个桶里有数的数 下记 fxxxf_{xxx}
  • 不妨设 dpjdp_j 表示 直到 fjf_j,场上还剩多少怪兽
  • 初始化 dp0=0dp_0 = 0 (场上还没有怪兽呢 QwQ)
  • 如果 fi>dpi1f_i > dp_{i-1} ,那么 fif_i 只怪兽中的 一部分 会把之前剩下的 dpi1dp_{i-1} 只怪兽都踹掉,自己就变成没被人欺负的(剩下的),另一部分直接变成“剩下的”,即 dpi=fidp_i = f_i
  • 如果 fidpi1f_i \le dp_{i-1} ,那么 fif_i 只怪兽 全部 会把之前剩下的 dpi1dp_{i-1} 只怪兽 中的 fif_i 只 都踹掉,自己就变成没被人欺负的(剩下的),dpi1dp_{i-1} 只剩下的怪兽 中另一部分还是“剩下的”,即 dpi=dpi1dp_i = dp_{i-1}
  • 整合上面两句话,状态转移方程 dpi=max(dpi1,fi)dp_i = \max(dp_{i-1},f_i)

这种做法也算不上 dp,只能算递推。

贴上AC Code,方便管理看:

#include <bits/stdc++.h>
#define pii pair<int,int>
#define x first
#define y second
using namespace std;
int n;
int a[100005];
map<int,int> f; // 遍历的时候更便利
int dp[100005];
int main() 
{
    cin >> n;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i];
        f[a[i]]++;
    }
    int j = 1;
    for(pii i : f)
    {
        if(i.y > dp[j-1]) dp[j] = i.y;
        else dp[j] = dp[j-1];
        // 方便理解,没有写成 dp[j] = max(i.y,dp[j-1])
        j++;
    }
    cout << dp[j - 1];
    return 0;
}

与众不同的实现:map
目前,题解区尚未有相同实现或讲的更详细的。

2024/10/27 11:06
加载中...