(UPCOJ暑期训练)Tally Counters

问题 D: Tally Counters

时间限制: 3 Sec  内存限制: 128 MB
提交: 126  解决: 19
[提交] [状态] [命题人:admin]
题目描述
A number of tally counters are placed in a row. Pushing the button on a counter will increment the displayed value by one, or, when the value is already the maximum, it goes down to one. All the counters are of the same model with the same maximum value.

Fig. D-1 Tally Counters
Starting from the values initially displayed on each of the counters, you want to change all the displayed values to target values specified for each. As you don't want the hassle, however, of pushing buttons of many counters one be one, you devised a special tool. Using the tool, you can push buttons of one or more adjacent counters, one push for each, in a single operation. You can choose an arbitrary number of counters at any position in each operation, as far as they are consecutively lined up.

How many operations are required at least to change the displayed values on counters to the target values?

 

输入
The input consists of multiple datasets, each in the following format.

n m 
a1 a2 ... an 
b1 b2 ... bn 
Each dataset consists of 3 lines. The first line contains n (1 ≤ n ≤ 1000) and m (1 ≤ m ≤ 10000), the number of counters and the maximum value displayed on counters, respectively. The second line contains the initial values on counters, ai (1 ≤ ai ≤ m), separated by spaces. The third line contains the target values on counters, bi (1 ≤ bi ≤ m), separated by spaces.

The end of the input is indicated by a line containing two zeros. The number of datasets does not exceed 100.

 

输出
For each dataset, print in a line the minimum number of operations required to make all of the counters display the target values.

 

样例输入

复制样例数据

4 5
2 3 1 4
2 5 5 2
3 100
1 10 100
1 10 100
5 10000
4971 7482 1238 8523 1823
3287 9013 9812 297 1809
0 0
样例输出
4
0
14731
题意:给定两个数组a,b,要求从a变到b,每次可以把任意位置任意长度序列加1,如果超过最大值m,则变为1,问最少操作次数。
方法,我的做法是采用动态规划
从a变到b,显然可以想到变为一个数组c[i]=(b[i]-a[i]+m)%m;
然后从第2个位置开始考虑,该位置一定可以从它的前一个位置转移而来,(如果a[i]<a[i-1],dp[i]=dp[i-1],如果a[i]>=a[i-1],dp[i]=dp[i-1]+a[i]-a[i-1])
然后坑点在于:本以为通过分析应该只有+m和不加m两种情况时间复杂度是O(2n),但wa了几发发现并不简单,可以转移0-n*m一共n个状态,实际时间复杂度为O(n2)。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
ll a[1005],b[1005];
ll dp[1005][1005];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,m;
    while(cin>>n>>m&&n+m)
    {
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++)
        {
            cin>>b[i];
            a[i]=(b[i]-a[i]+m)%m;
        }
        memset(dp,0x3f,sizeof dp);
        for(int i=0;i<n;i++) dp[1][i]=a[1]+i*m;
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<n;j++)
            {
                dp[i][j]=min(dp[i][j],dp[i-1][j]+max(0ll,a[i]-a[i-1]));
                if(j>0) dp[i][j]=min(dp[i-1][j-1]+m+a[i]-a[i-1],dp[i][j]);
                dp[i][j]=min(dp[i-1][j+1],dp[i][j]);
            }
 
        }
        ll ans=0x3f3f3f3f3f3f3f3f;
        for(int i=0;i<n;i++) ans=min(ans,dp[n][i]);
        cout<<ans<<endl;
    }
 
 
    return 0;
}

 

转载于:https://www.cnblogs.com/Suiyue-Li/p/11398446.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值