首页 > 其他分享 >ARC 028 D - 注文の多い高橋商店

ARC 028 D - 注文の多い高橋商店

时间:2023-01-25 17:35:21浏览次数:45  
标签:高橋 le 复杂度 sum ARC ans 方法 028 dp

题目意思

原题面

高橋商店では \(N\) 種類の商品が売られています。「どの種類の商品がいくつあるか」の情報が与えられるので、「合計 \(M\) 個の商品を選ぶ方法」の数を求めて下さい。ただし、同じ種類の商品は区別しないこととします。
いや、これは少し簡単過ぎるので、ちょっとした注文も追加しよう。整数 k, x からなる \(Q\) 個の注文を用意したので、それぞれについて「\(k_i\) 種類目の商品をちょうど \(x_i\) 個選ばなければならないとき、合計 \(M\) 個の商品を選ぶ方法」の数を求めて下さい。

DeepL 翻译后的题面

高桥商店出售 \(N\) 种类型的商品。 给出 "有多少种产品可供选择 "的信息,找出 "选择总共M种产品的方法 "的数量。 然而,我们将不对同一类型的产品进行区分。
不,这有点太容易了,所以让我们增加一个小订单。 我们有 \(Q\) 个由整数 \(k\) 和 \(x\) 组成的订单。对于每一个订单,请找出 "当正好要选择第 \(k_i\) 种产品的 \(x_i\) 个产品时,总共要选择 \(M\) 个产品的方法 "的数目。

数据范围

商品的种类个数:\(a_i\),\(k_i\le M\),\(x_i\le a_{x_i}\)。

  • \(10\%\) 的数据,\(N,M,Q \le 100\)

  • \(30\%\) 的数据,\(N,M\le 100,Q\le 5\cdot 10^5\)

  • \(80\%\) 的数据,\(N,M\le 2000,Q\le 1000\)

  • \(100\%\) 的数据,\(N,M\le 2000,Q\le 5\cdot 10^5\)

解题

方法 \(1\)

我们可以每一次询问单独做一个 dp。设计 \(dp_{i,j}\) 为到了第 \(i\) 种商品,已经选了 \(j\) 个的方案数。转移为 \(\displaystyle dp_{i,j}=\sum^{j}_{k=\max(0,j-a_i)} dp_{i-1,k}\)。保存前缀和,更新的时候就可以 \(O(1)\)。总复杂度 \(O(NMQ)\)。

期望得分 \(10\%\)。

方法 \(2\)

发现如果 \(x_i\) 不会对答案做贡献,可以预处理,枚举每一个 \(i\le N\),对于每一个除了 \(i\) 的做 dp。这样时间复杂度 \(O(N^2M)\)。

期望得分 \(30\%\)。

方法 \(3\)

发现每一次都重新计算一遍非常的麻烦,也很费时。

其实第 \(i\) 次也就是 \(i\) 影响了,那么 \(0\sim i\) 以及 \(i+1\sim N\) 其实是不需要重新计算的。这样维护两个 dp,一个前缀,一个后缀就可以了,每一次询问 \(O(M)\),总时间复杂度 \(O(QM+NM)\)。

期望得分 \(80\%\)。

方法 \(4\)

我们先用 「方法 \(1\)」里的 dp 计算一次,设答案数组为 \(dp\)。

定义 \(ans_{i,j}\) 为除了第 \(i\) 种选 \(j\) 个的方法数。很容易发现每一次询问要求的就是 \(ans_{k_i,m-x_i}\)。

\(ans\) 数组的转移为:\(ans_{i,j}=dp_{n,j}-\displaystyle \sum^{j-1}_{k=\max(0,j-a_i)} ans_{i,k}\)。这个式子很好理解。\(dp_{n,j}\) 多考虑了一些方案,就是选取了一些第 \(i\) 种的,这些需要减去。假设选了 \(k\) 个第 \(i\) 种,那么就还要选 \(j-k\) 个不是第 \(i\) 种的,也就是 \(ans_{i,j-k}\),于是就有了 \(\displaystyle \sum^{j-1}_{k=\max(0,j-a_i)} ans_{i,k}\)。

上面式子里的 \(\displaystyle \sum^{j-1}_{k=\max(0,j-a_i)} ans_{i,k}\) 可以用前缀和处理。复杂度 \(O(NM)\)。

期望得分 \(100\%\)。

代码
#include <bits/stdc++.h>

using namespace std;

#define dg(x) cout<<#x<<"="<<x<<endl

using ll = long long;

const int N = 2e3+3;
const int mod = 1e9+7;

ll n,m,q,a[N];
ll dp[N][N],ans[N][N],pre[N];

ll cal(int i){
	if (i<0){
		return 0;
	}
	return pre[i];
}

void precalc(){
	dp[0][0]=1;
	for (int i=0; i<=m; i++){
		pre[i]=1;
	}
	for (int i=1; i<=n; i++){
		for (int j=0; j<=m; j++){
			dp[i][j]=pre[j]-cal(j-a[i]-1);
			dp[i][j]=(dp[i][j]+mod)%mod;
		}
		pre[0]=dp[i][0];
		for (int j=1; j<=m; j++){
			pre[j]=pre[j-1]+dp[i][j];
			pre[j]%=mod;
		}
	}
}

void anscalc(){
	for (int i=1; i<=n; i++){
		for (int j=0; j<=m; j++){
			pre[j]=0;
		}
		ans[i][0]=pre[0]=1;
		for (int j=1; j<=m; j++){
			ll interval_sum=(pre[j-1]-cal(j-a[i]-1)+mod)%mod;
			ans[i][j]=(dp[n][j]-interval_sum+mod)%mod;
			pre[j]=pre[j-1]+ans[i][j];
			pre[j]%=mod;
		}
	}
}

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

	cin>>n>>m>>q;
	for (int i=1; i<=n; i++){
		cin>>a[i];
	}
	precalc();
	anscalc();
	while (q--){
		int k,x;
		cin>>k>>x;
		cout<<ans[k][m-x]<<endl;
	}
	return 0;
}

标签:高橋,le,复杂度,sum,ARC,ans,方法,028,dp
From: https://www.cnblogs.com/SFlyer/p/17067015.html

相关文章

  • (20)go-micro微服务Elasticsearch使用
    目录一Elasticsearch介绍二Elasticsearch的主要功能及应用场景1.Elasticsearch主要具有如下功能:2.Elasticsearch的主要应用场景如下:三Elasticsearch核心概念四Elasti......
  • ArcGIS工具 - 计算折点数量
    在GIS中,点构成线,线构成面,面构成体,维度增加,模型也加复杂。有时,我们需要统计线面等要素到底由多少个点构成,系统工具没有此功能,为源地理提供了三种解决方案。方法一折点转......
  • 题解 ARC154D【A + B > C ?】
    显然\(1+1>x\)对任意大于\(1\)的正整数\(x\)都不成立。利用这一点,我们可以在\(n-1\)次询问内问出\(1\)的位置。具体地,首先假设\(p_1\)为\(1\),记我们假设的为......
  • ARC 154
    A首先交换两个位置上的数并不会影响两个数的和。所以用基本不等式可以得出当两个数一个最小一个最大时乘积就最小。然后考虑怎么算高精度乘法。因为要取模,所以我们不用......
  • arc060
    感觉atcoder上的题克我啊。。。WebsiteC$O(n^4)$的DP很好想,题解说有$O(n^3)$的写法,大概是每个数都减去$A$就不用考虑选的数的个数这一维。CodeD根号分治......
  • ARC153F - Tri-Colored Paths
    题意给定一个\(n\)个点\(m\)条边的无向连通图,求将\(m\)条边进行\(3\)染色且满足:存在一条简单路径,使得路径上三种颜色的边各有至少一条。的方案数。数据范围:\(......
  • archlinux将python更换到3.11
    python更换到3.11版本安装python3.11首先利用yay-Spython311生成缓存文件,在~/.cache/yay/python311接着去官网下载一个python3.11的包,https://aur.archlinux.org/pack......
  • archlinux连接Github与本地
    连接Github与本地首先右键打开gitbash,然后输入下面命令:gitconfig--globaluser.name"vconlln"gitconfig--globaluser.email"[email protected]"用户名和......
  • archlinux手机投屏
    多屏协同......
  • arch安装vmware
    1.安装VM的依赖包sudopacman-Sfuse2gtkmmlinux-headerspcsclitelibcanberrancursesyay-Sncurses5-compat-libs#aur里面的依赖包2.安装VMyay-Svm......