NC214458. 台灯
描述
^-^买了一盏新台灯,台灯的亮度可以通过遥控器上的两个按钮调整,一共有m级亮度,由1到m之间的整数表示。
第一个按钮是“变亮”按钮。当这个按钮被按下去时,台灯的亮度会增加1,当原先亮度为m时亮度会变为1。
第二个按钮是“默认”按钮。当这个按钮被按下去时,台灯的亮度会变成^-^设定的亮度x。
^-^正在考虑如何设定亮度x,使得他能按最少的按钮完成下面的操作。
最初灯的亮度为,接下来他想依次看到亮度为。
即完成的亮度变化最少需要按多少次按钮。
你需要求出^-^在设定了最优的x的情况下最少需要按多少次按钮。
输入描述
第一行输入两个整数n,m。
第二行输入n个整数,代表^-^想看到的n个亮度。
输出描述
一个整数,表示^-^在设定了最优的x的情况下最少需要按多少次按钮。
示例1
输入:
4 6 1 5 1 4
输出:
5
说明:
示例2
输入:
10 10 10 9 8 7 6 5 4 3 2 1
输出:
45
C++(g++ 7.5.0) 解法, 执行用时: 21ms, 内存消耗: 2248K, 提交时间: 2022-09-06 20:50:38
#include <cstdio> #include <algorithm> #define orep(i,a,b) for(auto i=(a); i< (b); ++i) #define crep(i,a,b) for(auto i=(a); i<=(b); ++i) #define NL putchar(10); #define REDIR freopen("data.in", "r", stdin); int main() { int n, m; scanf("%d%d", &n, &m); long long dp[m*2+2]={}; int arr[n+1]; scanf("%d", arr+1); long long rst = 0; crep(i, 2, n) { scanf("%d", arr+i); const int l = arr[i-1], r = arr[i]<l ? arr[i]+m : arr[i]; rst += r-l; if (r > l+1) { dp[l+2] += 1; dp[r+1] -= r-l; dp[r+2] += r-l-1; } } crep(i, 1, m*2) { dp[i] += dp[i-1]; } crep(i, 1, m*2) { dp[i] += dp[i-1]; } long long diff = -1; crep(i, 1, m) { diff=std::max(diff, dp[i]+dp[i+m]); } printf("%lld", rst - diff); return 0; }
C++(clang++11) 解法, 执行用时: 12ms, 内存消耗: 2768K, 提交时间: 2021-01-22 21:37:21
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=1e5+5,mod=1e9+7; ll a[N],b[N<<1]; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); ll n,m; cin>>n>>m; ll tot=0; for(int i=1;i<=n;i++) { cin>>a[i]; if(i<2) continue; int x=a[i-1],y=(a[i]>x?0:m)+a[i]; tot+=y-x; if(y>=x+2) b[x+2]+=1,b[y+1]+=x-y,b[y+2]+=y-x-1; } for(int i=1;i<m<<1;i++) b[i]+=b[i-1]; for(int i=1;i<m<<1;i++) b[i]+=b[i-1]; ll mx=b[m]; for(int i=m+1;i<m<<1;i++) mx=max(mx,b[i-m]+=b[i]); cout<<tot-mx<<endl; return 0; }