首页 > 其他 > 详细

减操作

时间:2020-05-07 01:25:43      阅读:79      评论:0      收藏:0      [点我收藏+]

题面

给定一个整数数组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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!