數字DP CQOI2016 手機號碼

2022-05-20 08:02:42 字數 3119 閱讀 1093

這題的要求的是組成該數的數字滿足一些條件的數,並且看資料範圍,果斷鎖定數字dp。

考場上我寫記憶化搜尋的把自己搞暈了,然後果斷改寫遞推版。

f表示<=n的滿足條件的**號碼,定義狀態7維

f[ff][i][j][f1][f2][f3][l]  //是否比n小  當前是第幾位  幾個連續  是否3個連續   是否有8  是否有4 當前選擇的數字是什麼
狀態轉移十分複雜(寫著複雜),但是思維難度不大,只要有耐心就能寫對。

具體方程看我的**。 an

s=ca

l(r)

−cal

(l−1

)

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

ll f[2][20][5][2][2][2][10]; //第幾位 幾個連續 是否3個連續 8 4

ll l,r;

int d[20],len;

template

void read(t &x)

}/*ll dfs(int i,int j,bool tr,bool et,bool fu,int d,bool ff)

if(!ff&&~f[i][j][tr][et][fu])

return f[i][j][tr][et][fu];

ll ret=0;

int j,mx=ff?d[i-1]:9;

if(d==8)

if(j==2)

}*/void dp() //第幾位 幾個連續 是否3個連續 8 4

for(i=1;i<=len;i++)

else

if(j==4)

else

f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][k];

f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][k];

f[0][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][k];}}

else

else

if(j==4)

else

f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][j]+f[0][i-1][2][0][1][0][j];

f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][j]+f[0][i-1][2][0][0][1][j];

f[0][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][j]+f[0][i-1][2][0][0][0][j];}}

}j=d[i];

for(k=0;k1];k++)

else

if(d[i]==4)

else

f[1][i][0][1][0][1][d[i]]+=f[0][i-1][0][1][0][1][k];

f[1][i][0][1][1][0][d[i]]+=f[0][i-1][0][1][1][0][k];

f[1][i][0][1][0][0][d[i]]+=f[0][i-1][0][1][0][0][k];}}

else

else

if(d[i]==4)

else

f[1][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][d[i]]+f[0][i-1][2][0][1][0][d[i]];

f[1][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][d[i]]+f[0][i-1][2][0][0][1][d[i]];

f[1][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][d[i]]+f[0][i-1][2][0][0][0][d[i]];}}

}if(d[i]!=k)

else

if(d[i]==4)

else

f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][k];

f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][k];

f[1][i][0][1][0][0][d[i]]+=f[1][i-1][0][1][0][0][k];}}

else

else

if(d[i]==4)

else

f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][d[i]]+f[1][i-1][2][0][1][0][d[i]];

f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][d[i]]+f[1][i-1][2][0][0][1][d[i]];

f[1][i][0][1][0][0][d[i]]+=f[1][i-1][0][1][0][0][d[i]]+f[1][i-1][2][0][0][0][d[i]];}}

}}ll cal(ll n)

d[0]=9;

if(len<11)

d[++len]=0;

memset(f,0,sizeof f);

dp();

for(int i=0;i0][len][0][1][0][0][i]+f[0][len][0][1][0][1][i]+f[0][len][0][1][1][0][i];

ret+=f[1][len][0][1][0][0][d[len]]+f[1][len][0][1][0][1][d[len]]+f[1][len][0][1][1][0][d[len]];

return ret;

// for(i=0;i<=mx;i++)

// return dfs(len,0,1,0,1,1)+dfs(len,0,1,1,0,1);

}int main()

數字dp CQOI2016 手機號碼

題目描述 人們選擇手機號碼時都希望號碼好記 吉利。比如號碼中含有幾位相鄰的相同數字 不含諧音不吉利的數字等。手機運營商在發行新號碼時也會考慮這些因素,從號段中選取含有某些特徵的號碼單獨 為了便於前期規劃,運營商希望開發乙個工具來自動統計號段中滿足特徵的號碼數量。工具需要檢測的號碼特徵有兩個 號碼中要...

1002 手機靚號

手機靚號 time limit 1000ms memory limit 65536k total submit 470 accepted 208 description description 小風涼剛買了手機,去營業廳開戶,營業員讓其挑選自己喜歡的號碼,但那麼多的號碼著實讓他眼花,他對號碼的要求是...

1176 手機靚號

1176 手機靚號 description 小風剛買了手機,去營業廳開戶,營業員讓其挑選自己喜歡的號碼,但那麼多號碼著實讓他眼花,他對號碼的要求是在號碼中6和8的個數要不少於5個,並且沒有數字4,於是請你給他編了乙個程式。input 輸入不多於50組的數,手機號碼 每個數以13或15開頭,長為11位...