小明最近在研究乙個數字刪除遊戲,正要考考佳佳。遊戲規則如下
給定乙個正整數,去掉其中若干個數字後剩下的數字按原左右次序將組成乙個新的正整數。請問最少刪去幾個數字,能夠使得這個新的正整數合法(不含前導0)且是3的倍數。
小明寫下的數字太大,佳佳一時處理不了。請你幫他寫乙個程式處理出結果吧!
第一行乙個整數n(n≤5),表示小明寫下了n正整數
第2~n+1行每行乙個正整數ai(ai≤10100000),數字的長度可能達到100001位。
共n行,每行乙個整數,表示最少刪去的數字的個數。如果沒有合法的方案,請輸出「err」(不含引號)。
3
1234
1000
2
1
3err
第一組刪除1個留下的整數為234或123。
第二組刪除3個留下的整數為0。
因為不能有前導零,方便起見從右往左推,考慮dp[i][j]
代表從最後乙個位置到第i
位求和後對3取模等於j
時最少需要刪幾個數字,設第i位的數字為num[i]
,比較容易得到轉移方程:dp
[i][
j]=m
in(d
p[i+
1][j
]+1,
dp[i
+1][
(j−(
num[
i]%3
)+3)
%3] dp[
i][j
]=mi
n(dp
[i+1
][j]
+1,d
p[i+
1][(
j−(n
um[i
]%3)
+3)%
3]
然後我們從左往右列舉最優答案的起點,如果當前點num[i]
不為零的話代表可以列舉,假設最優解是從第i
位開始的,那麼之前的i-1
位數字全都刪去,然後這個最優解需要刪去的總數字個數就是i−
1+dp
[i+1
][(3
−num
[i]%
3+3)
%3] i−1
+dp[
i+1]
[(3−
num[
i]%3
+3)%
3]
答案取一下最小值就可以了。
#include
const
int maxn = int(1e5) + 7, inf = 0x3f3f3f3f;
int n, num[maxn], mod[maxn], dp[maxn][3], ans;
char s[maxn];
int main()
if (ans == inf) puts("err");
else
printf("%d\n", ans);
}return
0;}
數字動態規劃
如果發現有些數字題目需要處理的資料多,而且單個數處理數字計數時會隨著數的變大越來越麻煩 通常都這樣 就適合這種方法或者這種思想解決問題。因為通常遇到這方面的題目通常會考察乙個連續區間內符合某條件的數,這樣可以將單個數的位操作合一,直接看題目條件內所有的數的條件符合情況,即直接處理所有數可能的所有位以...
動態規劃 UPC 7780(狀壓DP)
時間限制 2 sec 記憶體限制 128 mb 題目描述 給定一張 n n 20 個點的帶權無向圖,點從 0 n 1 標號,求起點 0 到終點 n 1 的最短hamilton路徑。hamilton路徑的定義是從 0 到 n 1 不重不漏地經過每個點恰好一次。輸入第一行乙個整數n。接下來n行每行n個整...
動態規劃 數字DPwindy
include include include using namespace std define ll long long const int maxn 2e9 10 ll f 20 20 設f i,j 表示由前i位數字構成且最高位數字為j的windy數有多少個 ll a 20 void ini...