减操作

题面

给定一个整数数组a1,a2,…,an。

定义数组第 i 位上的减操作:把ai和ai+1换成ai−ai+1。

用con(a,i)表示减操作,可以表示为:

con(a,i)=[a1,a2,…,ai−1,ai−ai+1,ai+2,…,an]
长度为 n 的数组,经过 n−1 次减操作后,就可以得到一个整数 t。

例如数组[12,10,4,3,5]经过如下操作可得到整数4:

con([12,10,4,3,5],2) = [12,6,3,5]

con([12,6,3,5] ,3) = [12,6,-2]

con([12,6,-2] ,2) = [12,8]

con([12,8] ,1) = [4]

现在给定数组以及目标整数,求完整操作过程。

输入格式

第1行包含两个整数n和t。

第2..n+1行:第i行包含数组中的第 i 个整数ai。

输出格式

输出共n-1行,每行包含一个整数,第 i 行的整数表示第 i 次减操作的操作位置。

数据范围

1≤n≤100,
−10000≤t≤10000,
1≤ai≤100

输入样例:

5 4
12
10
4
3
5

输出样例:

2
3
2
1

题解

自己随便画一下会发现 最后是

a[1] - a[2] ± a[3] ± a[4] ... ± a[n]

发现 n * ai范围 挺小, 明显是线性dp

#include <bits/stdc++.h>
using namespace std;

const int maxn = 105;
const int p = 10000;

int n, t, a[maxn], f[maxn][p << 1 | 1], ans[maxn];

int main()
{
    cin >> n >> t;
    for (int i = 1;i <= n; ++i) cin >> a[i];

    f[1][p + a[1]] = 1; f[2][a[1] - a[2] + p] = -1;
    for (int i = 3; i <= n; ++i)
        for (int j = 0; j <= (p << 1); ++j)
           if(f[i - 1][j])
           {
              if (a[i] + j >= 0 && a[i] + j <= (p << 1)) f[i][a[i] + j] = 1;
              if (j - a[i] >= 0 && j - a[i] <= (p << 1)) f[i][j - a[i]] = -1;
           }

    for (int i = n, cur = p + t; i >= 2; cur -= a[i] * ans[i--]) 
        ans[i] = f[i][cur];

    for (int i = 2, cnt = 0; i <= n; ++i) 
        if(ans[i] == 1) cout << i - (cnt++) - 1 << '\n';

    for(int i = 2; i <= n; ++i) 
        if(ans[i] == -1) cout<< 1 << '\n';
    return 0;
}

原文链接: https://www.cnblogs.com/2aptx4869/p/12839579.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    减操作

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/346708

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午4:04
下一篇 2023年3月2日 上午4:04

相关推荐