首页 > 其他分享 >AGC041D Problem Scores 题解

AGC041D Problem Scores 题解

时间:2024-08-29 19:14:17浏览次数:5  
标签:前缀 int 题解 AGC041D 分值 Problem dp mod

在分值不降的条件下,要使任意一个大小为 \(k\) 的子集 \(S\) 内题目的分值之和少于任意一个大小为 \(k + 1\) 的子集 \(T\) 内题目的分值之和,容易发现只需要取 \(S\) 为后 \(k\) 道题目,\(T\) 为前 \(k + 1\) 道题目时满足限制即可。

换而言之,只需要对满足 \(a\) 的每一段长为 \(k + 1\) 的前缀的和大于对应的长为 \(k\) 的后缀的和的方案计数。

为了方便,可以把分值不降的限制转化为:初始令所有 \(a_i = n\),每次选择一个前缀并整体减一,但必须保证所有 \(a_i\) 为正整数。

朴素地,设 \(dp_{i, a, b}\) 表示已经处理完前缀 \(i\),前缀和为 \(a\),后缀和为 \(b\) 的方案数。

套路地,设差分变量:\(j = a - b\),为了合法,令 \(j > 0\)。\(dp_{i, j}\) 表示已经处理完前缀 \(i\),前缀和减后缀和为 \(j\) 的方案数。

容易描述每次选择前缀并整体减一后 \(j\) 的变化。问题就转化为一个完全背包问题:有 \(n\) 种物品,每种物品有无限个,物品的体积确定,问总体积小于 \(n\) 的条件下可以选择的最多的物品数量。

再套路地压缩第一维,跑完全背包即可。时间复杂度 \(O(n^2)\)。

参考代码如下。(需要指出代码中的背包是反过来跑的)

#include <iostream>

#define int long long

using namespace std;

int n, mod;
int w[5005];
int dp[5005];

signed main() {
#ifndef ONLINE_JUDGE
    freopen("AGC041D.in", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> mod;
    for (int i = 1; i <= (n + 1) / 2; ++i)
        w[i] = i;
    for (int i = n; i > n / 2; --i)
        w[i] = n - i + 1;
    dp[n] = 1;
    for (int i = 1; i <= n; ++i)
        for (int j = n; j >= w[i]; --j)
            dp[j - w[i]] = (dp[j - w[i]] + dp[j]) % mod;
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        ans += dp[i];
    cout << ans % mod << endl;
    return 0;
}

标签:前缀,int,题解,AGC041D,分值,Problem,dp,mod
From: https://www.cnblogs.com/bluewindde/p/18387435

相关文章

  • P7075 [CSP-S2020] 儒略日 题解
    P7075[CSP-S2020]儒略日题面:题目描述为了简便计算,天文学家们使用儒略日(Julianday)来表达时间。所谓儒略日,其定义为从公元前4713年1月1日正午12点到此后某一时刻间所经过的天数,不满一天者用小数表达。若利用这一天文学历法,则每一个时刻都将被均匀的映射到数轴......
  • luoguP4907 A换B problem
    数据有点水,加个卡时就可以过。代码加注释送上:#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<ctime>#defineLLlonglongusingnamespacestd;LLread(){ LLk=0,f=1;charc=getchar(); while(c<......
  • AT_ddcc2017_final_d なめらかな木 题解
    首先考虑暴力DP,设\(f(i,v_1,v_2,now)\)为已经将前\(i\)个数填入,\(i\)填在\(v_1\),\(j\)填在\(v_2\)点,已经填完点的状态是\(now\)(状压一下存在一个longlong里)的方案数。转移时直接枚举下一个点暴力转移,只需要保证新的点没有被访问过,并且填上新点后,\(v_1\)的所有邻接......
  • Luogu P4425 转盘 题解 [ 黑 ] [ 线段树 ] [ 贪心 ] [ 递归 ]
    转盘:蒟蒻的第一道黑,这题是贪心和线段树递归合并的综合题。贪心破环成链的trick自然不用多说。首先观察题目,很容易发现一个性质:只走一圈的方案一定最优。这个很容易证,因为再绕一圈回来标记前面的和等前面的标记完之后继续走是等价的,并且再绕一圈甚至可能更劣。于是,我们只用走......
  • 题解:P9938 [USACO21OPEN] Acowdemia II B
    前言:原来的tj干了一堆什么建图啊之类的,但其实不要这么复杂。注:下文中\(n\)是各成员名字列表。从\(K=1\)开整。如果情况是\(n_i<n_{i+1}<\cdots<n_j\),那么显然,咱就不知道关于成员\(n_i,\cdots,n_j\)的相对资历的信息。也许所有这帮成员都做出了相同的贡献。......
  • AWTF2024A Moving Slimes 题解
    发现史莱姆不合并也不会影响答案,所以就不用考虑合并了。这样处理之后,史莱姆的移动可以看作是受到与其不在同一位置的史莱姆的吸引所完成的,每只史莱姆可以给其他史莱姆一个单位的吸引力。因为每只史莱姆提供的吸引力是恒定的,所以考虑把吸引力放在它们的重心上,设\(pre_i\)表示坐......
  • 历年CSP-J初赛真题解析 | 2016年CSP-J初赛阅读程序(23-26)
    学习C++从娃娃抓起!记录下CSP-J备考学习过程中的题目,记录每一个瞬间。附上汇总贴:历年CSP-J初赛真题解析|汇总_热爱编程的通信人的博客-CSDN博客#include<iostream>usingnamespacestd;intmain(){intmax,min,sum,count=0;inttmp;cin>>tmp;......
  • CF1286E Fedya the Potter Strikes Back 题解
    题目链接点击打开链接题目解法牛题!题目实际上是要每次加入一个字符,求所有的\(border\)的神秘度之和考虑从前\(i-1\)个字符到前\(i\)个字符\(border\)的变化如果\(str_1=str_i\),会加入长度为\(1\)的\(border\),这一部分可以暴力加且只会保留\(i-1\)的\(border......
  • 华为java岗经典面试题解析
    题目为在一个整形的数组中,在数组中只有一值个是不重复的,其他的值都是有两个重复的值,找出不重复的那个值。{11,11,12,13,13,16,16}解析为当用Java来解决这个问题时,可以使用异或运算来找出只出现一次的元素。以下是一个示例Java程序,演示了如何在一个整型数组中找出只出现一次的元......
  • 洛谷P5322 [BJOI2019] 排兵布阵 题解
    代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintdp[20001],a[101][101],s,n,m;signedmain(){ cin>>s>>n>>m; for(intj=1;j<=s;j++){ for(inti=1;i<=n;i++){ cin>>a[i][j]; } } for(inti=1;......