+ Generating function example (hdu 2079 + hdu 2082)
Although ACM was a little powerless, but still perseverance, continue Ken Ken algorithm. . . . .
Yesterday afternoon, a mother learn learning function, discrete mathematics + power series , can only say nb ...
Read principles for a long time, the result but it is still not too clear to see, and began to see the board and the board title
This is yesterday's blog to see the two heavyweights:
generating function (for beginners is most easily understood)
The second board is really good, so he looked at the board began to knock on the title board (did not start this afternoon)
Example one:
Subject to the effect is very simple: n credits requires repair, and k sets of each set of data will be given credit to v [i], the number of courses corresponding to n [I] data
how many combinations will eventually be required
This question is do begin to understand the generating function, combined with the board's blog The second, in conjunction with their own coding habits knocked two of his own board:
A template:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int a[50]; //最后结果
int b[50]; //中间结果
int n[50]; //每个物品的数量
int v[50]; //每个物品对应的价值或权重
int main(){
int t; //样例个数
int N,K; //N表示需要获得的学分,k表示右多少组
scanf("%d",&t);
while(t--){
scanf("%d%d",&N,&K);
for(int i=0;i<K;i++){
scanf("%d%d",&v[i],&n[i]);
}
//初始化a
memset(a,0,sizeof(a));
a[0]=1;
for(int i=0;i<K;i++){ //循环每个因子
memset(b,0,sizeof(b));
for(int j=0;j<=n[i]&&j*v[i]<=N;j++){ //循环每个因子的每一项
for(int k=0;k+j*v[i]<=N;k++){ //循环a的每一项
b[k+j*v[i]]+=a[k]; //把结果加到对应位
}
}
memcpy(a,b,sizeof(b)); //b赋值给a
}
printf("%d\n",a[N]);
}
return 0;
}
Template II:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n[50]; //每个物品的数量
int v[50]; //每个物品的价值或权重
int a[50]; //计算结果
int b[50]; //中间结果
int last,last2;
int main(){
int t; //样例个数
int N,K; //N表示需要获得的总学分,K表示多少组记录
scanf("%d",&t);
while(t--){
scanf("%d%d",&N,&K);
for(int i=0;i<K;i++){
scanf("%d%d",&v[i],&n[i]);
}
//初始化a,因为有last,所以这里无需初始化其他位
a[0]=1;
last=0;
for(int i=0;i<K;i++){
last2=min(last+n[i]*v[i],N); //计算下一次的last
memset(b,0,sizeof(int)*(last2+1)); //只清空b[0...last2]
for(int j=0;j<=n[i]&&j*v[i]<=last2;j++){ //这里是last2
for(int k=0;k<=last&&k+j*v[i]<=last2;k++){ //一个是last,一个是last2
b[k+j*v[i]]+=a[k];
}
}
memcpy(a,b,sizeof(int)*(last2+1)); //b赋值给a,只赋值0...last2
last=last2; //更新last
}
printf("%d\n",a[N]);
}
return 0;
}
This question could not see more than two templates a template to be optimized, but hdu 2082 can be very clearly seen
Example two:
Topic effect: very simple, that is, each letter corresponding value, then the number of each letter will be given, and then seek a word from these letters how many species (premise: alphabetical order different as the same word )
Want to start a complex, thought it should be a quadruple loop, in fact, it is a little can make a simple judgment on the basis of a question on
The following code does not write too much comment
Code One:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define ll long long
#define pi acos(-1.0)
using namespace std;
int a[55];
int b[55];
int n[55];
int v[55];
int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=0;i<26;i++){
scanf("%d",&n[i]);
v[i]=i+1;
}
ll sum=0;
memset(a,0,sizeof(a));
a[0]=1;
for(int i=0;i<26;i++){
memset(b,0,sizeof(b));
for(int j=0;j<=n[i]&&j*v[i]<=50;j++){
for(int k=0;k+j*v[i]<=50;k++){
b[k+j*v[i]]+=a[k];
}
}
memcpy(a,b,sizeof(b));
}
/**如果价值不大于50,则记录到结果*/
for(int i=1;i<=50;i++){
if(a[i])
sum+=a[i];
}
printf("%lld\n",sum);
}
return 0;
}
Code II:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
int a[55];
int b[55];
int n[55];
int v[55];
int last,last2;
int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=0;i<26;i++){
scanf("%d",&n[i]);
v[i]=i+1;
}
a[0]=1;
last=0;
for(int i=0;i<26;i++){
last2=min(last+n[i]*v[i],50);
memset(b,0,sizeof(int)*(last2+1));
for(int j=0;j<=n[i]&&j*v[i]<=last2;j++){
for(int k=0;k<=last&&k+j*v[i]<=last2;k++){
b[k+j*v[i]]+=a[k];
}
}
memcpy(a,b,sizeof(int)*(last2+1));
last=last2;
}
ll sum=0;
/**如果价值不大于50,则记录到结果*/
for(int i=1;i<=50;i++){
if(a[i])
sum+=a[i];
}
printf("%lld\n",sum);
}
return 0;
}
Numb, just add a line comment, and then the same time actually has. . .
This type of problem, we must first think of the future generating function, generating function is very easy to use