洛谷P1934封印(前缀和加dp,一直错改了好久)

说说前面我错了哪里:int没有改为longlong导致有几个测试点是wa,然后初始[0]没有为0导致了输出是负值,总之很崩溃写这道题,,,,,

#include <stdio.h>
#include <limits.h>

int main() {
    int n, t;
    scanf("%d %d", &n, &t);

    long long a[1005];
    long long f[1005];
    long long sum[1005] = { 0 };

    for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
        sum[i] = sum[i - 1] + a[i];//前缀和
        f[i] = LLONG_MAX;//在动态规划中,我们经常将某个状态初始化为一个较大的值,然后通过状态转移方程逐步更新最小值。
    }



    f[0] = 0;//这里很重要,要初始化为0,不然答案就是负数,因为会越界



    for (int i = 1; i <= n; i++) {
        f[i] = (f[i] < f[i - 1] + a[i] * (long long)n * n) ? f[i] : f[i - 1] + a[i] * (long long)n * n;//前i-1个已经是最优,后一个破一层
        for (int j = 1; j < i; j++) {
            if (a[i] + a[j] <= t) {
                f[i] = (f[i] < f[j - 1] + (a[i] + a[j]) * (sum[i] - sum[j - 1])) ? f[i] : f[j - 1] + (a[i] + a[j]) * (sum[i] - sum[j - 1]);
            }//前j-1个已经是最优,后j到i连着破
        }
    }




    printf("%lld", f[n]);

    return 0;
}

 外层for是单独破层,内层循环是多层破,(这两个循环不能反过来),f[i]维护的是局部最优

简单模拟1:

3 10
8 5 7
180
f(1)=72
f(2)=72+45
不符合判断条件
f(3)=72+45+63=180

 

简单模拟2:
6 14
8 5 7 9 3 5
457
f(1) = 8 * 36 = 288
f(2) = 288 + 5 * 36 = 468
符合判断
f(2)' =169
f(3) = 169 + 7 * 36 = 421
f(3)'=f(1)+12*12=432
f(4) = 432 + 9 * 36 = 756
f(4)'=f(2)+14*21>432
f(5) = 432 + 3 * 36
f(5)'=(8+3)*32=352
f(5)'' = f(1) + 8 * 24 = 480
f(5)'''=f(2)+10*19=359
f(5)'''' = f(3)+12*12>352
f(6)=352+5*26=532
f(6)'=13*(8+5+7+9+3+5)=481
f(6)''=288+10*29>481
f(6)'''=169+12*24=457
f(6)''''=f(3) + 14 * 17>457
f(6)'''''=f(4)+64>457

 

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值