组合数学 - 母函数 + 模板总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | // Memory Time // 1347K 0MS // by : Snarl_jsb // 2014-09-19-18.23 #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<climits> #include<cmath> #define N 1000010 #define LL long long using namespace std; int n; int c1[N],c2[N]; int val[N],cnt[N]; int main() { ios_base::sync_with_stdio( false ); cin.tie(0); // freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin); // freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout); while (cin>>n) //n种类型的物品 { long long sum=0; for ( int i=1;i<=n;++i) { cin>>val[i]>>cnt[i]; //单位价值 数量 sum+=val[i]*cnt[i]; } memset(c1,0, sizeof (c1)); memset(c2,0, sizeof (c2)); for ( int i=0;i<=cnt[1]*val[1];i+=val[1]) { c1[i]=1; } for ( int i=2;i<=n;++i) { for ( int j=0;j<=sum;++j) { for ( int k=0;k<=cnt[i];++k) { c2[k*val[i]+j]+=c1[j]; // 不要忘了加号 } } for ( int j=0;j<=sum;++j) { c1[j]=c2[j]; c2[j]=0; } } // ............ 剩下的就根据题目来变形 //c1[i]:取出一些物品,这些物品价值的和为i的取法有c1[i]种 for ( int i=0;i<=sum;++i) { printf( "%d " ,c1[i]); } puts( "" ); } return 0; } //另: //每种物品都有无限个 /* // //第1种物品的价值为1,有无限个; //第2种物品的价值为2,有无限个; //第3种物品的价值为3,有无限个; //....... //问取出一些物品的价值总和为n的取法有多少个? #include <iostream> using namespace std; const int _max = 10001; int c1[_max], c2[_max]; // c1是保存各项质量砝码可以组合的数目 // c2是中间量,保存每一次的情况,维持c1的不变性 int main() { int nNum; int i, j, k; while(cin >> nNum) //要组合的目标数 { for(i=0; i<=nNum; ++i) // ---- ① 首先对c1初始化,由第一个表达式(1+x+x2+..xn)初始化,把质量从0到n的所有砝码都初始化为1. { c1[i] = 1; c2[i] = 0; } for(i=2; i<=nNum; ++i) // ----- ②i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。 { for(j=0; j<=nNum; ++j) // -----③j 从0到n遍历,这里j就是只一个表达式里第j个变量,比如在第二个表达式里:(1+x2+x4....)里,第j个就是x2*j. for(k=0; k+j<=nNum; k+=i) // ---- ④ k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。 { c2[j+k] += c1[j]; } for(j=0; j<=nNum; ++j) // ---- ⑤把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的 { c1[j] = c2[j]; c2[j] = 0; } } cout << c1[nNum] << endl; } return 0; } */ |
作者:北岛知寒
出处:https://www.cnblogs.com/crazyacking/p/3982095.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?