1. 程式人生 > >【動態規劃】Column Addition @ICPC2017Tehran/upcexam5434

【動態規劃】Column Addition @ICPC2017Tehran/upcexam5434

時間限制: 1 Sec 記憶體限制: 128 MB
題目描述

A multi-digit column addition is a formula on adding two integers written like this:
這裡寫圖片描述
A multi-digit column addition is written on the blackboard, but the sum is not necessarily correct. We can erase any number of the columns so that the addition becomes correct. For example, in the following addition, we can obtain a correct addition by erasing the second and the forth columns.
這裡寫圖片描述


Your task is to find the minimum number of columns needed to be erased such that the remaining formula becomes a correct addition.
輸入
There are multiple test cases in the input. Each test case starts with a line containing the single integer n, the number of digit columns in the addition (1 ⩽ n ⩽ 1000). Each of the next 3 lines contain a string of n digits. The number on the third line is presenting the (not necessarily correct) sum of the numbers in the first and the second line. The input terminates with a line containing “0” which should not be processed.
輸出
For each test case, print a single line containing the minimum number of columns needed to be erased.
樣例輸入
3
123
456
579
5
12127
45618
51825
2
24
32
32
5
12299
12299
25598
0
樣例輸出
0
2
2
1

給你一個只有兩個數相加的,長度為n列的加法豎式,問最少刪去幾列使得豎式成立。
設兩個相加的數為a和b,和為c
如果要使第i列的等式成立,應該滿足下面四種情況的一種:
1. a[i]+b[i] == c[i]; 剛好
2. a[i]+b[i]-10 == c[i]; 產生進位
3. a[i]+b[i]+1 == c[i]; 接受進位後成立
4. a[i]+b[i]+1-10 == c[i]; 接受進位成立且產生進位
我是從左往右推,令dp[i][0] (i from 1)表示第i位不接受進位時,最少刪去的列數;
令dp[i][1] 表示第i位接受進位時,最少刪去的列數;
因為第n位一定不接受進位,所以輸出dp[n][0]表示答案;
轉移方程詳見程式碼
讀者也可嘗試從右往左推

#define IN_LB() freopen("F:\\in.txt","r",stdin)
#define IN_PC() freopen("C:\\Users\\hz\\Desktop\\in.txt","r",stdin)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
const int INF = 0x3f3f3f3f;
int a[maxn],b[maxn],c[maxn],dp[maxn][2];
int main() {
//    IN_LB();
    int n;
    while(scanf("%d",&n)&&n) {
        for(int i=1; i<=n; i++)scanf("%1d",a+i);
        for(int i=1; i<=n; i++)scanf("%1d",b+i);
        for(int i=1; i<=n; i++)scanf("%1d",c+i);
        dp[0][1] = INF;
        for(int i=1; i<=n; i++) {
            if(a[i]+b[i]==c[i]) {
                dp[i][0] = dp[i-1][0];
            } else if(a[i]+b[i]-10==c[i]) {
                dp[i][0] = min(dp[i-1][0]+1,dp[i-1][1]);
            } else dp[i][0] = dp[i-1][0]+1;
            if(a[i]+b[i]+1 ==c[i]) {
                dp[i][1] = min(dp[i-1][1]+1,dp[i-1][0]);
            } else if(a[i]+b[i]+1-10==c[i]) {
                dp[i][1] = dp[i-1][1];
            } else dp[i][1] = dp[i-1][1]+1;
        }
        printf("%d\n",dp[n][0]);
    }
    return 0;
}