列表

详情


NC25459. 烹饪

描述

“你已经是一个成熟的孩子了,要学会自己烹饪了!”

小 Y 上山拜师学艺,经过 年之长的厨艺练习,已成为当世名厨,今天他接受邀请,在众人面前展示自己高超的厨艺。

人们给小 Y 提供了 种食物,每种食物无限量供应,每种食物都有一个美味值,记为 a_i

小 Y 为了展示他的厨艺,他需要挑选出食材,使自己可以烹饪出任意正整数美味值的菜肴,初始时菜肴的美味值为 每次加入一种食材,他可以选择让菜肴的美味值上升 a_i,也可以选择让菜肴的美味值下降 a_i(或许最后会弄出来黑暗料理?)。

作为当世名厨,小 Y 自然知道该怎么挑选食材最佳。可是他并不知道有多少种最佳的挑选食材方案,于是他找到了你来帮忙。

我们使用无序数列来表示从原来的n种食材中挑选出了m种食材,第i种食材编号为b_i的方案。同时你需要注意,为同一种方案且当时,

最佳的挑选食材方案指,挑选出 食材(),让他们能够组合出任意正整数美味值的菜肴

例如,当时,都是最佳的挑选食材方案

答案对 取模。

输入描述

第一行一个正整数 
第二行 个正整数

输出描述

输出一个数表示最佳的挑选食材方案的数量对 取模。

示例1

输入:

5
1 2 3 4 5

输出:

26

示例2

输入:

1
2

输出:

0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 416ms, 内存消耗: 23824K, 提交时间: 2020-03-24 11:19:39

#include <bits/stdc++.h>
using namespace std;

const int MAXN=3010;
int mod=998244353;
int dp[MAXN][2010];
int arr[MAXN];
int n;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",arr+i);
    for(int i=1;i<=n;i++){
        dp[i][arr[i]]=1;
        for(int j=1;j<=2000;j++){
            int gcd=__gcd(j,arr[i]);
            dp[i][j]+=dp[i-1][j];
            dp[i][gcd]=(dp[i-1][j]+dp[i][gcd])%mod;
        }
    }
    printf("%d",dp[n][1]);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 225ms, 内存消耗: 488K, 提交时间: 2019-09-15 11:28:36

#include <cstdio>
#include <algorithm>

int n, a;
int f[2001];

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a);
		for (int j = 1; j <= 2000; j++)
			if (f[j]) (f[std::__gcd(a, j)] += f[j]) %= 998244353;
        f[a]++;
    }
	printf("%d", (long long)f[1] % 998244353);
}

上一题