简单/复杂整数划分

这个题我做过类似的题目,没错,又是记忆化搜索,但也不完全是,还是用搜索就可以过,本质也是动态规划

基本上只要会简单的,就会做复杂的,只不过是步骤麻烦点

#include<bits/stdc++.h>
using namespace std;
int n,a[1000010]={1},res=1;
void dfs(int t,int s)//现在的数总和是t,用了s个加号
{
    for(int i=1;i<=t;i++)
        if(i>=a[s-1])//如果符合字典序(即不会重复)
        {
            a[s]=i;
            t-=i;
            if(t==0) res++;//如果是0,就直接加一
            else dfs(t,s+1);
            t+=i;//恢复状态
        }
}
int main()
{
    while(cin>>n)
    {
        res=1;
        memset(a,0,sizeof a);//清空状态;
        dfs(n,1);
        cout<<res<<endl;
    }
}

接下来是复杂的,没啥区别,只是多个判断步骤

#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,k,a[N];
int diyige,dierge,disange;//第一个第二个第三个
void judge(int num)//判断函数,看看这个状态属于第几个,注意这里可能一种组合属于多个状态,所以不能直接返回
{
    if(num==k) diyige++;
    bool f=false;
    for(int i=1;i<=num;i++)
        for(int j=1;j<=num;j++)
            if(i!=j&&a[i]==a[j])
            {
                f=true;
                break;
            }
    if(!f) dierge++;
    f=false;
    for(int i=1;i<=num;i++)
        if(a[i]%2==0&&a[i]!=1)
        {
            f=true;
            break;
        }
    if(!f) disange++;
}
void dfs(int x,int num)
{
    for(int i=1;i<=x;i++)
        if(i<=n&&i>=a[num-1])
        {
            a[num]=i;
            x-=i;
            if(x==0) judge(num);
            else dfs(x,num+1);
            x+=i;
        }
}
int main()
{
    while(cin>>n>>k)
    {
        memset(a,0,sizeof a);
        diyige=0,dierge=0,disange=0;
        //memset(vis,false,sizeof vis);
        dfs(n,1);
        cout<<diyige<<endl;
        cout<<dierge<<endl;
        cout<<disange<<endl;
    }
    return 0;
}

 

;

posted @ 2023-05-24 12:53  o-Sakurajimamai-o  阅读(16)  评论(0)    收藏  举报
-- --