目次
トピック: P1025 [NOIP2001 改善グループ] Number Division - Luogu | コンピュータ サイエンス教育の新しいエコロジー (luogu.com.cn)
前に書かれています:
どうすればアルゴリズムをうまく学習できますか?
個人的には質問の体系的なブラッシングが特に重要だと思いますが、
そのため、深さ優先探索を上手に学ぶために、暴力的な探索を使ってブルーブリッジカップに対処するために、
さっそくクイズを始めましょう!
タイトル: P1025 [NOIP2001 改善グループ] Number Division - Luogu | コンピュータ サイエンス教育の新しいエコロジー (luogu.com.cn)
タイトル説明:
入力形式:
n, k (6 < n ≤ 200,2 ≤ k ≤ 6)
出力フォーマット:
1 つの整数、つまり異なる分割。
入力サンプル:
7 3
出力例:
4
ヒント:
4 つの区分は、1、1、5、1、2、4、1、3、3、2、2、3
です。
問題解決のアイデア:
深さ優先探索を使うと、
最初の注意点は、検索の順序です。
確認したいので、
すべてのケースをトラバースできる再帰構造を作成しました。
(上記の再帰的検索の基本的な考え方に慣れておくことは常に良いことです)
次は具体的なアイデア です:
まず、トピックの条件に従って再帰的な検索ツリーを描画します。
ルート ノード: (例として、タイトルに示されている例を取り上げます)
最初の位置から始めて、1 から始まる数字を埋めます。
この質問では、次の数値が前の数値以上である必要があります。
トピックの最大要件は 7 であり、3 から始まる最小合計も 9 であることがわかりました。
彼は違法であり、剪定が必要であると直接判断できます。
再帰的に検索を続けます:
1 + 4 + 4 > 7、2 + 3 + 3 > 7 の場合、これら 2 つのケースも後で剪定する必要があることがわかりました。
剪定の法則を要約すると、実際には次のようになります。
現在の値の合計+残りのポジション数*初期値>質問で要求された値の場合、
再帰検索を続ける必要はありません。
再帰的に検索を続けます:
このルールに従ってコードを実装できます: (整理することを忘れないでください)
コード:
//包含常用头文件
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, k;
//因为题目只需要返回计数,所以不用专门开一个数组记录,直接用一个变量计数即可
int res = 0;
void dfs(int u, int start, int sum)
{
//遍历完三个位置
if(u > k)
{
//如果符合条件
if(sum == n)
res++;
return;
}
//如果当前的sum + 接下来剩下位置的数量 * 起始数值 > 题目要求的值,就不用继续递归搜索了
for(int i = start; sum + i * (k - u + 1) <= n; i++)
{
dfs(u + 1, i, sum + i);
}
}
int main()
{
cin >> n >> k;
dfs(1, 1, 0);
printf("%d\n", res);
return 0;
}
交流 !!!!!!!!!!
最後に書く:
以上がこの記事の内容です、お読みいただきありがとうございます。
この記事が気に入ったら、いいねとコメントをお願いします。また、ご意見をお書きください。
私と一緒にプログラミングを学びたい場合は、私に従ってください。私たちは一緒に学び、成長します。
今後もより質の高いコンテンツを出力していきますので、よろしくお願いします。