hdu 1028 Ignatius and the Princess III 整数划分+dp 组合

10 篇文章 0 订阅
3 篇文章 0 订阅

#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int f[122];
void init()
{
    int i,j;
    memset(f,0,sizeof(f));
    f[0]=1;
    for(i=1;i<=120;i++)
        for(j=i;j<=120;j++)
        f[j]+=f[j-i];       //每次加的都是最大值是i的方案数
}
int main()
{
    init();
    int n;
    while(cin>>n)
    {
        cout<<f[n]<<endl;
    }
    return 0;
}
/*
    这个dp类似背包,用1到i的数,去塞满容积为i的背包;
    f[i]表示,i的整数划分方案数;
*/



当n很大的时候,用dp的方法就不行了,例如hdu4671,直接用公式求救OK了:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
using namespace std;
const int mod=1e9+7;
int f[100010];
void init()
{
    f[0]=1;
    int i,j,k,flag=1;
    for(i=1;i<=100000;i++)
    {
        f[i]=0;
        for(j=1;;j++)
        {
            int t=i-j*(3*j-1)/2;
            int tt=i-j*(3*j+1)/2;
            if(j&1)
                flag=1;
            else
                flag=-1;
            if(t<0&&tt<0)
                break;
            if(t>=0)
                f[i]=(f[i]+flag*f[t]);
            if(tt>=0)
                f[i]=(f[i]+flag*f[tt]);
        }
    }
}
int main()
{
    init();
    int n;
    while(cin>>n)
    {
        cout<<f[n]<<endl;
    }
    return 0;
}
/* 
题意:将n拆分成多个正整数之和,问有多少种拆法? 
如5=1+1+1+1+1=1+1+1+2=1+1+3=1+4=5=1+2+2=2+3.共7种 
 
Input: 
2 
100000 
99999 
 
Output: 
49037875  
677525748 
 
方法: 
直接公式:f[n]=∑(-1)^(k-1)*(f[n-k*(3*k-1)/2]+f[n-k*(3*k+1)/2]) 
            其中n-k*(3*k-1)/2>=0,n-k*(3*k+1)/2>=0; 
        注意两个条件要分开判断,有大于0的就加上相应的f,不是两个同时成立或者不成立 
*/ 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值