sum_N问题

SUM——N

target: g_s
data:g_n: g_w[1----n-1]

#include <stdio.h>
#include <stdlib.h>

enum {
    ZERO = 0,
    ONE,
    TWO,
    DATALEN = 5,
    N = 110,

    DataErr = -2,
    SUMErr = -1,
    DataSuss = 0,
    DATAEQ,
    SUMEQ,
    SUMBIGGER,
};

int g_n = 7, g_s = 15;
int g_w[N] = { 1, 4, 3, 4, 5, 2, 7 };
int g_ans[N] = {0};    // 保存最后的结果
int g_currSum = 0;
int g_currIdx = 0;

int GetNSW()
{
    int res = scanf_s("%d%d", &g_n, &g_s);
    if (res < TWO) {
        return DataErr;
    }
    int sum = 0;
    for (int i = 0; i < g_n; ++i) {
        res = scanf_s("%d", &g_w[i]);
        if (res < ONE) {
            return DataErr;
        }
        if (g_w[i] == g_s) {
            return SUMEQ;
        }
        sum += g_w[i];
    }

    if (sum < g_s) {
        return SUMErr;
    } else if (sum == g_s) {
        return SUMEQ;
    } else {
        return DataSuss;
    }
}

int NSumProc(int idx)
{
    if (idx == g_n) {
        return DataSuss;
    }
    if (g_currSum == g_s) {
        return SUMEQ;
    }
    int countIn = 0;
    int res;
    for (int i = idx; i < g_n; ++i) {
        // count in
        countIn = g_currSum + g_w[i];
        if (countIn <= g_s) {
            g_ans[g_currIdx] = g_w[i];
            g_currSum = countIn;
            ++g_currIdx;
            res = NSumProc(i + 1);
            if (res == SUMEQ) {
                return SUMEQ;
            }
            --g_currIdx;
            g_ans[g_currIdx] = 0;
            g_currSum -= g_w[i];
        }
        // no count
        res = NSumProc(i + 1);
        if (res == SUMEQ) {
            return SUMEQ;
        }
    }
    return DataSuss;
}

int main()
{
    
    int res = GetNSW();
    if (res == DATAEQ || res == SUMEQ) {
        printf("YES");
        return 0;
    } else if (res < DataSuss) {
        printf("NO");
        return 0;
    }

    memset(g_ans, 0, sizeof(g_ans));
    g_currSum = g_currIdx = 0;
    res = NSumProc(0);
    if (res == SUMEQ) {
        printf("YES");
    } else {
        printf("NO");
    }
    return 0;
}

有超时,先对数据进行排序,减去多余的分支:

#include <stdio.h>
#include <stdlib.h>

enum {
    ZERO = 0,
    ONE,
    TWO,
    DATALEN = 5,
    N = 110,

    DataErr = -2,
    SUMErr = -1,
    DataSuss = 0,
    DATAEQ,
    SUMEQ,
    SUMBIGGER,
};

int g_n = 7, g_s = 15;
int g_w[N] = { 1, 4, 3, 4, 5, 2, 7 };
int g_ans[N] = {0};  // 保存最后的结果
int g_currSum = 0;
int g_currIdx = 0;

int GetNSW()
{
    int res = scanf_s("%d%d", &g_n, &g_s);
    if (res < TWO) {
        return DataErr;
    }
    int sum = 0;
    for (int i = 0; i < g_n; ++i) {
        res = scanf_s("%d", &g_w[i]);
        if (res < ONE) {
            return DataErr;
        }
        if (g_w[i] == g_s) {
            return SUMEQ;
        }
        sum += g_w[i];
    }

    if (sum < g_s) {
        return SUMErr;
    } else if (sum == g_s) {
        return SUMEQ;
    } else {
        return DataSuss;
    }
}

int QCmp(const void *a, const void *b)
{
    return *(const int *)a - *(const int *)b;
}

int NSumProc(int idx)
{
   ---if (idx == g_n) {
        return DataSuss;----  不能加,如果在最后一个索引时刚好等于target,在这里会提前返回NO,直接删掉
    }-----
    if (g_currSum == g_s) {
        return SUMEQ;
    }
    int countIn = 0;
    int res;
    for (int i = idx; i < g_n; ++i) {
        countIn = g_currSum + g_w[i];
        if (countIn <= g_s) {
            // count in
            g_ans[g_currIdx] = g_w[i];
            g_currSum = countIn;
            ++g_currIdx;
            res = NSumProc(i + 1);
            if (res == SUMEQ) {
                return SUMEQ;
            }
            --g_currIdx;
            g_ans[g_currIdx] = 0;
            g_currSum -= g_w[i];
            // no count
            res = NSumProc(i + 1);
            if (res == SUMEQ) {
                return SUMEQ;
            }
        } else {
            break;
        }
    }
    return DataSuss;
}

int main()
{
    int res = GetNSW();
    if (res == DATAEQ || res == SUMEQ) {
        printf("YES");
        return 0;
    } else if (res < DataSuss) {
        printf("NO");
        return 0;
    }

    qsort(g_w, g_n, sizeof(int), QCmp);  // 先排序,可以剪枝
    memset(g_ans, 0, sizeof(g_ans));

    g_currSum = g_currIdx = 0;
    res = NSumProc(0);
    if (res == SUMEQ) {
        printf("YES");
    } else {
        printf("NO");
    }

    return 0;
}

#include <stdio.h>
#include <stdlib.h>

enum {
    ZERO = 0,
    ONE,
    TWO,
    DATALEN = 5,
    N = 110,

    DataErr = -2,
    SUMErr = -1,
    DataSuss = 0,
    DATAEQ,
    SUMEQ,
    SUMBIGGER,
};

int g_n, g_s;
int g_w[N];

int GetNSW()
{
    int res = scanf_s("%d%d", &g_n, &g_s);
    if (res < TWO) {
        return DataErr;
    }
    int sum = 0;
    for (int i = 0; i < g_n; ++i) {
        res = scanf_s("%d", &g_w[i]);
        if (res < ONE) {
            return DataErr;
        }
        if (g_w[i] == g_s) {
            return SUMEQ;
        }
        sum += g_w[i];
    }

    if (sum < g_s) {
        return SUMErr;
    } else if (sum == g_s) {
        return SUMEQ;
    } else {
        return DataSuss;
    }
}

int QCmp(const void *a, const void *b)
{
    return *(const int *)a - *(const int *)b;
}

int MaryProcKAdder(int numOfAdder, int *lastestStartIdx)
{
    int currSum = 0;
    int idx;
    for (idx = 0; idx < numOfAdder; ++idx) {
        currSum += g_w[idx];
    }

    for (idx = ONE; currSum < g_s && idx <= *lastestStartIdx; ++idx) {
        currSum += g_w[idx + numOfAdder - ONE] - g_w[idx - ONE];
    }

    if (currSum == g_s) {
        return SUMEQ;
    } else if (currSum > g_s) {
        *lastestStartIdx = idx;
        return SUMBIGGER;
    }

    return DataSuss;
}

int MaryProc()
{
    qsort(g_w, g_n, sizeof(int), QCmp);

    int numOfAdder;
    int lastestStartIdx = g_n - TWO;
    int startIdx = lastestStartIdx;
    int res;
    for (numOfAdder = 2; numOfAdder < g_n; ++numOfAdder) {
        startIdx = g_n - numOfAdder;
        lastestStartIdx = lastestStartIdx <  startIdx ? lastestStartIdx : startIdx;
        res = MaryProcKAdder(numOfAdder, &lastestStartIdx);
        if (res == SUMEQ) {
            printf("YES");
            return 0;
        }
    }
    printf("NO");
    return 0;
}

int main()
{
    int res = GetNSW();
    if (res == DATAEQ || res == SUMEQ) {
        printf("YES");
        return 0;
    } else if (res < DataSuss) {
        printf("NO");
        return 0;
    }

    MaryProc();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值