0
点赞
收藏
分享

微信扫一扫

x+2y+3z=n的非负整数解数


题目:给定一个正整数

x+2y+3z=n的非负整数解数_ci

,范围是

x+2y+3z=n的非负整数解数_ios_02

,对于方程

x+2y+3z=n的非负整数解数_#include_03

,其中

x+2y+3z=n的非负整数解数_#include_04


x+2y+3z=n的非负整数解数_ci_05


x+2y+3z=n的非负整数解数_ios_06

为非负整数,求有多     少个这样的三元组

x+2y+3z=n的非负整数解数_#include_07

满足此等式。

 

 

分析:本题最暴力的做法就是直接嵌套循环枚举,这样时间复杂度很大,不可取。仔细想想,先看

x+2y+3z=n的非负整数解数_#include_08


     这个等式的非负整数解数目为


                           

x+2y+3z=n的非负整数解数_#include_09


     然后再看方程

x+2y+3z=n的非负整数解数_#include_03

,设


                           

x+2y+3z=n的非负整数解数_#include_11


     那么方程解的总数目为


    

x+2y+3z=n的非负整数解数_#include_12


     所以枚举就行了。


代码:

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long LL;

LL work(LL n)
{
    LL ans = 0;
    for(int k = 0; k <= n / 3; k++)
        ans += (n - 3 * k) / 2 + 1;
    return ans;
}

int main()
{
    LL n;
    while(cin>>n)
        cout<<work(n)<<endl;
    return 0;
}


实际上,对于上面得到的结果可以继续进行优化的。要分类讨论


 1. 当

x+2y+3z=n的非负整数解数_ci

为奇数时


    针对每一个

x+2y+3z=n的非负整数解数_ci_14

,如果

x+2y+3z=n的非负整数解数_ci_14

为奇数,那么

x+2y+3z=n的非负整数解数_ios_16

是偶数,所以

x+2y+3z=n的非负整数解数_#include_17

本身就是整数,不用管。而如果

x+2y+3z=n的非负整数解数_ci_14

是偶    数,那么

x+2y+3z=n的非负整数解数_ios_16

就是奇数了,这样就有


   

x+2y+3z=n的非负整数解数_ci_20


   (1)如果

x+2y+3z=n的非负整数解数_ios_21

为奇数,此时得到最终答案是


       

x+2y+3z=n的非负整数解数_ios_22


   (2)如果

x+2y+3z=n的非负整数解数_ci_23

为偶数,那么最终答案是


      

x+2y+3z=n的非负整数解数_ci_24


   

 2. 当

x+2y+3z=n的非负整数解数_ci

为偶数时


    针对每一个

x+2y+3z=n的非负整数解数_ci_14

,如果

x+2y+3z=n的非负整数解数_ci_14

为奇数,那么

x+2y+3z=n的非负整数解数_ios_16

为奇数,而


    

x+2y+3z=n的非负整数解数_ci_20


    如果

x+2y+3z=n的非负整数解数_ci_14

为偶数,那么

x+2y+3z=n的非负整数解数_ios_16

为偶数,所以

x+2y+3z=n的非负整数解数_#include_17

就是它本身。


   (1)如果

x+2y+3z=n的非负整数解数_ci_23

为奇数,那么最终答案是


      

x+2y+3z=n的非负整数解数_ci_34


   (2)如果

x+2y+3z=n的非负整数解数_#include_35

为偶数,最终答案是


       

x+2y+3z=n的非负整数解数_ci_36


代码:

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long LL;

LL work(LL n)
{
    LL k = n / 3;
    LL t = (k + 1) * n - 3 * k * (k + 1) / 2;
    LL ans = k + 1;
    if(k & 1) t -= (k + 1) / 2;
    else if(n & 1) t -= (k / 2 + 1);
    else t -= k / 2;
    t >>= 1;
    return ans + t;
}

int main()
{
    LL n;
    while(cin>>n)
        cout << work(n) << endl;
    return 0;
}

 

 

举报

相关推荐

0 条评论