+ Generating function example (hdu 2079 + hdu 2082)

+ 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)

Detailed generating function and history of the most common and most efficient generating function template

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:

hdu 2079: elective time

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;
}

Here Insert Picture Description

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;
}

Here Insert Picture Description

This question could not see more than two templates a template to be optimized, but hdu 2082 can be very clearly seen

Example two:

hdu 2082: look for the word

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;
}

Here Insert Picture Description

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;
}

Here Insert Picture Description

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

Published 127 original articles · won praise 32 · views 10000 +

Guess you like

Origin blog.csdn.net/boliu147258/article/details/102762457