您的位置:首页 > 其它

【bzoj4513】储能表【数位DP】

2016-04-26 19:56 281 查看

本来是想去学数位DP,作死挑了这道题,爆炸。。。

听说正确姿势应该是去做bzoj4521【手机】,听说迪克们当场都A了,Orz

然后对于4513,我只想说,一、脸、懵、逼

首先,我是无论如何都无法想到f[i][x][y][z]精妙的表示方式的

……讲不下去了,搬来罗爷爷的blog救场http://yyhslyz.is-programmer.com/posts/199294.html

好吧我承认这道题我完全没理解。。。。

代码可以看lych的blog.

不过其中又get了一个bug,原来<的优先级大于^,2333

-----------------------------------------------

首先,数位dp是啥.

它一般与二进制,异或有关,有些比较容易看出来,有些并不.

解决问题的核心思想就是逐位确定.

我还是想再说一遍,感觉自己做dp题还是没有任何的长进,可能弱菜看过的题太少.

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define mo 998244353
using namespace std;
ll x,y,n,dp[15][10][10][2][2][2][2];
int a[110];
ll solve(ll x)
{
n=0;int p,q,r;
while(x)
{
a[++n]=x%10;x/=10;
}
if(n!=11)return 0;
for(int i=1;i<=n/2;i++)swap(a[i],a[n-i+1]);
memset(dp,0,sizeof(dp));
for(int i=1;i<a[1];i++)
for(int j=0;j<=9;j++){
if(i==4||j==4)p=1;else p=0;
if(i==8||j==8)q=1;else q=0;
dp[2][i][j]

[q][0][0]=1; } for(int j=0;j<a[2];j++){ if(a[1]==4||j==4)p=1;else p=0; if(a[1]==8||j==8)q=1;else q=0; dp[2][a[1]][j][p][q][0][0]=1; } if(a[1]==4||a[2]==4)p=1;else p=0; if(a[1]==8||a[2]==8)q=1;else q=0; dp[2][a[1]][a[2]][p][q][0][1]=1; for(int i=2;i<n;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) for(int I=0;I<=1;I++) for(int J=0;J<=1;J++) for(int K=0;K<=1;K++) for(int l=0;l<=9;l++){ if(l==4)p=1;else p=I; if(l==8)q=1;else q=J; if(l==j&&l==k)r=1;else r=K; dp[i+1][k][l][p][q][r][0]+=dp[i][j][k][I][J][K][0]; if(l<a[i+1])dp[i+1][k][l][p][q][r][0]+=dp[i][j][k][I][J][K][1]; else if(l==a[i+1])dp[i+1][k][l][p][q][r][1]+=dp[i][j][k][I][J][K][1]; } ll ans=0; for(int i=0;i<=9;i++) for(int j=0;j<=9;j++) for(int k=0;k<=1;k++) ans+=dp [i][j][0][0][1][k]+dp [i][j][1][0][1][k]+dp [i][j][0][1][1][k]; return ans; } int main() { scanf("%lld%lld",&x,&y); printf("%lld\n",solve(y)-solve(x-1)); }

View Code [p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: