第七章 数学 6 AcWing 1593. 整数分解

- 日理万妓 2024-03-31 10:34 198阅读 0赞

第七章 数学 6 AcWing 1593. 整数分解

原题链接

AcWing 1593. 整数分解

算法标签

数学 数论 DP 背包问题

思路

类似AcWing 12. 背包问题求具体方案
把n看成背包的容积N
因为n最多不超过400,然而p进制最少为2
所以物品的价值最大可以取到20(因为20^2 = 400)
所以这道题目就被转化成
从前i个物品中取,体积恰好为j,重量恰好为k的取法的方案的最大价值
所以根据闫氏dp分析法我们可以得到状态转移的方程
f[i][j][k] = max(f[i-1][j][k],f[i][j - v[i]][k - w[i]] + value[i]);

详细思路
问题转换

在这里插入图片描述
在这里插入图片描述

方案计算

在这里插入图片描述
状态转移方程
在这里插入图片描述
在这里插入图片描述

方案选择

在这里插入图片描述

时间复杂度

由于n最多不超过400,p进制最少为2,所以物品的价值最大可以取到20(因为20^2 = 400)。
时间复杂度 20 ∗ 400 ∗ 400 = 3200000 < 1 0 7 20*400*400 = 3200000 < 10^7 20∗400∗400=3200000<107,所以可以用dp来进行求解

代码

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #include<bits/stdc++.h>
  4. #define int long long
  5. #define x first
  6. #define y second
  7. #define ump unordered_map
  8. #define ums unordered_set
  9. #define pq priority_queue
  10. #define rep(i, a, b) for(int i=a;i<b;++i)
  11. #define Rep(i, a, b) for(int i=a;i>=b;--i)
  12. using namespace std;
  13. typedef pair<int, int> PII;
  14. const int N=405, INF=0x3f3f3f3f3f3f3f3f;
  15. const double Exp=1e-8;
  16. //int t, n, m, cnt, ans;
  17. int n, k, p, f[21][N][N];
  18. inline int rd(){
  19. int s=0,w=1;
  20. char ch=getchar();
  21. while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
  22. while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
  23. return s*w;
  24. }
  25. void put(int x) {
  26. if(x<0) putchar('-'),x=-x;
  27. if(x>=10) put(x/10);
  28. putchar(x%10^48);
  29. }
  30. int pw(int a, int b){
  31. int res=1;
  32. rep(i, 0, b){
  33. res*=a;
  34. }
  35. return res;
  36. }
  37. signed main(){
  38. ios::sync_with_stdio(false);
  39. cin.tie(0);
  40. cout.tie(0);
  41. n=rd(), k=rd(), p=rd();
  42. memset(f, -INF, sizeof f);
  43. f[0][0][0]=0;
  44. int m;
  45. for(m=1;;m++){
  46. int v=pw(m, p);
  47. if(v>n){
  48. break;
  49. }
  50. rep(i, 0, n+1){
  51. rep(j, 0, k+1){
  52. f[m][i][j]=f[m-1][i][j];
  53. if(i>=v&&j){
  54. f[m][i][j]=max(f[m][i][j], f[m][i-v][j-1]+m);
  55. }
  56. }
  57. }
  58. }
  59. m--;
  60. if(f[m][n][k]<0){
  61. puts("Impossible");
  62. }else{
  63. printf("%lld = ", n);
  64. bool is_first=true;
  65. while(m){
  66. int v=pw(m, p);
  67. while(n>=v&&k&&f[m][n-v][k-1]+m==f[m][n][k]){
  68. if(is_first){
  69. is_first=false;
  70. }else{
  71. printf(" + ");
  72. }
  73. printf("%lld^%lld", m, p);
  74. n-=v, k--;
  75. }
  76. m--;
  77. }
  78. }
  79. return 0;
  80. }

参考文献

AcWing 1593. 整数分解(PAT甲级辅导课)y总视频讲解

原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,198人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数学

    说明:本文翻译自《TangoRefMan\_Sep\_1\_2008》 由于本人是编程初学者,对很多程序设计概念不是非常熟悉,编程经验不多,再加上英语水平不高,翻译纯属一个D