這題的要求的是組成該數的數字滿足一些條件的數,並且看資料範圍,果斷鎖定數字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位...