group_allocation.dart 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import 'package:flutter/material.dart';
  2. import 'tool_kit.dart';
  3. /// 分组分配:n 个人分成 k 个**有区别的**组(组不空着)。
  4. ///
  5. /// 先把 n 个人分成 k 堆(第二类斯特林数 S(n,k),堆之间不区分),
  6. /// 再把 k 堆分给 k 个有名字的组(k! 种)—— 所以答案是 k!·S(n,k)。
  7. class GroupAllocationPage extends StatefulWidget {
  8. const GroupAllocationPage({super.key});
  9. @override
  10. State<GroupAllocationPage> createState() => _GroupAllocationPageState();
  11. }
  12. class _GroupAllocationPageState extends State<GroupAllocationPage> {
  13. final _n = ToolField('n (人数)', hint: '正整数', keyboard: TextInputType.number);
  14. final _k = ToolField('k (组数)', hint: '正整数', keyboard: TextInputType.number);
  15. @override
  16. Widget build(BuildContext context) => ToolScaffold(
  17. title: '分组分配',
  18. fields: [_n, _k],
  19. intro: const Text('把 n 个人分成 k 个有区别的组(每组至少一人)\n'
  20. '方案数 = k! · S(n, k),S 是第二类斯特林数'),
  21. compute: (session) async {
  22. final n = int.tryParse(_n.text);
  23. final k = int.tryParse(_k.text);
  24. if (n == null || n < 1) throw Exception('n 要填一个正整数');
  25. if (k == null || k < 1) throw Exception('k 要填一个正整数');
  26. return [
  27. ...await exactAndApprox(
  28. session,
  29. '方案数 k!·S($n,$k)',
  30. 'Factorial[$k]*StirlingS2[$n, $k]',
  31. ),
  32. ToolText(
  33. '斯特林数 S($n,$k)',
  34. (await session.compute('StirlingS2[$n, $k]')).text,
  35. ),
  36. ];
  37. },
  38. );
  39. }