关于#c++#的问题,请各位专家解答!

使用枚举法会超时,如何减少时间复杂度。c++
已知有n项活动和每一项所需的时间,活动编号从1到n,每项活动在周六和周日各开展一次。 小明决定周六和周日分别参加编号连续的k项活动,而且不会重复参加同一种活动(即若在某一天选择参加了活动m,则在另一天不会再参加活动m)。 请帮忙找出周六和周日花费的总时间最少的选择。

输入
第一行为一个整数n和一个整数k,n代表有n项活动,k代表小明周六和周日每天参加的活动数量,n和k用空格隔开。
接下来的一行为n个整数,分别表示一项活动完成的时间,用空格隔开。

输出
输出为两个整数,表示周六和周日选择的起始活动编号。如果有多个方案,请输出周六起始活动编号较小的方案;如果仍有多个方案,请输出周日起始活动编号较小的方案。

例1输入:
5 2
6 1 8 2 1
例1输出:
1 4
解释:
根据“参加编号连续的k项活动”要求,可供小明选择的活动安排有:
方案一、周六参加编号1和2的k项活动,时长分别为6和1;周日参加编号3和4的k项活动,时长分别为8和2。
方案二、周六参加编号1和2的k项活动,时长分别为6和1;周日参加编号4和5的k项活动,时长分别为2和1。
方案三、周六参加编号2和3的k项活动,时长分别为1和8;周日参加编号4和5的k项活动,时长分别为2和1。
方案四、周六参加编号3和4的k项活动,时长分别为8和2;周日参加编号1和2的k项活动,时长分别为6和1。
方案五、周六参加编号4和5的k项活动,时长分别为2和1;周日参加编号1和2的k项活动,时长分别为6和1。
方案六、周六参加编号4和5的k项活动,时长分别为2和1;周日参加编号2和3的k项活动,时长分别为1和8。
在这6种活动安排方案中,总时间最少的是方案二和方案五, 根据题目要求,应选择周六起始活动编号较小的方案二,输出周六和周日的起始活动编号1和4。


```c++
#include 
using namespace std;
int a[50000];
int main()
{
    int n = 0, k = 0;
    cin >> n >> k;
    for (int i = 0; i < n; i++)cin >> a[i];
    int res = 100000000;
    int ans1 = 0, ans2 = 0;
    for (int i = 0; i <= n - 2 * k; i++)
    {
        int tmp1 = 0,tmp2=0;
        for (int j = i; j < i + k; j++)
        {
            tmp1 += a[j];
        }
        int p = i + k;
        for (; p <= n-k; p++)
        {
            tmp2 = tmp1;
            for (int q = p; q < p + k; q++)
            {
                tmp2 += a[q];
            }
            if (tmp2 < res)
            {
                res = tmp2; ans1 = i+1; ans2 = p+1;
            }
        }
    }
    cout << ans1 << " " << ans2 << endl;
    return 0;
}


```

空间换时间的方法,用一个数组存放k项活动总时间,避免重复循环求和。

#include <iostream>
using namespace std;

int a[50000], s[50000]; //s[i] = a[i] + a[i+1] + ... + a[i+k]

int main() {
    int n = 0, k = 0, i, j, t;
    cin >> n >> k;
    for (i = 0; i < n; i++)cin >> a[i];
    for (t = 0, i = 0; i < k; i++)t += a[i];
    //计算连续k项活动消耗时间 
    for (s[i - k] = t; i < n; i++) {
        t = t - a[i - k] + a[i];
        s[i - k+1] = t;
    }
    int min,r1=0,r2=0;
    //给minint类型最大的数
    for(i=0;i<sizeof(int)*8-1;i++){
        min|=1<<i;
    }
    //枚举 
    for(i=0;i<n-2*k+1;i++){
        for(j=i+k;j<n-k+1;j++){
            if(s[i]+s[j]<min){
                min=s[i]+s[j];
                r1=i+1;
                r2=j+1;
            }
        }
    }
    cout << r1 << " " << r2 << endl;
    return 0;
}

该回答引用ChatGPT
实现代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    vector<int> a(n), s(n+1);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        s[i+1] = s[i] + a[i];
    }
    int min_sum = 2e9, min_start = 0;
    for (int i = 1; i <= n-k+1; i++) {
        for (int j = i+k; j <= n-k+2; j++) {
            int sum = s[i+k-1] - s[i-1] + s[j+k-1] - s[j-1];
            if (sum < min_sum) {
                min_sum = sum;
                min_start = i;
            }
        }
    }
    cout << min_start << " " << min_start+k << endl;
    return 0;
}