タイトルはすべてです。各部K Iが所与のアレイr
ため = K I < = R Iの範囲でなければならない場合k個の数値の和としてnを書く方法の数。各部分に制限があります。
Iはk
部品の合計としてn
を分割する必要があります。例えば
-
n = 4, k = 3 and r = [2, 2, 1]
ans = 2
#[2, 1, 1], [1, 2, 1]
注文事項。 (2,1,1)と(1,2,1)とは異なる。
私は星と棒の方法を使ってそれを解決することを教えましたが、上限のためにそうです。 i私はそれに近づくことを知りません。
私は直接再帰関数を実装しましたが、小さな値に対してのみうまく動作します。元の問題の
制約
1 <= n <= 10
7
1 <= k <= 10
5
1 <= r
i
<= 51
すべての計算は、モジュロの素数の下で行われます。
私は同様の問題を発見しましたが、私はプログラムでどのように実装するのか分かりません。 HERE
マイブルートフォース再帰関数 -
#define MAX 1000
const int md = 1e9 + 7;
vector <int> k;
vector <map<int, int>> mapper;
vector <int> hold;
int solve(int sum, int cur){
if(cur == (k.size() - 1) && sum >= 1 && sum <= k[cur]) return 1;
if(cur == (k.size() - 1) && (sum < 1 || sum > k[cur])) return 0;
if(mapper[cur].find(sum) != mapper[cur].end())
return mapper[cur][sum];
int ans = 0;
int start = 1;
for(int i=start; i<=k[cur]; ++i){
int remain = sum - i;
int seg = (k.size() - cur) - 1;
if(remain < seg) break;
int res = solve(sum - i, cur + 1);
ans = (1LL * ans + res) % md;
}
mapper[cur][sum] = ans;
return ans;
}
int main(){
for(int i=0; i<MAX; ++i) k.push_back(51); // restriction for each part default 51
mapper.resize(MAX);
cout << solve(MAX + MAX, 0) << endl;
}
代わりの計算の結果を格納するためのマップを使用して、私は2次元配列を使用し、それは非常に良好なパフォーマンスの向上を与えたが、私は大きいためのそれを使用することはできませんnおよびk値。
どのように私の再帰関数を改善するか、この問題を解決する他の方法は何ですか?
可能であれば、元の問題のリンクを教えてください。上限はすべてのパーティションで同じであれば、はるかに簡単になりますが、明らかに提供した例からではありません。 – Suparshva
'k'は常に' r'のサイズと同じですか? – ImaginaryHuman072889
@ ImaginaryHuman072889はい、常にあります。 – Atul