您的位置:首页 > 其它

hdu3507 Print Article(斜率优化dp)

2016-08-23 15:44 253 查看

hdu3507

题目

大概题意就是要输出N个数字a
,输出的时候可以连续连续的输出,每连续输出一串,它的费用是 “这串数字和的平方加上一个常数M”。

思路

http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html

这位博主已经说的很好了。

就是在写递推公式的时候,可以化成g[k,j] < sum[i]这种形式,貌似sum[i]还要具有单调性,我们就可以用斜率优化dp来优化。(手动模拟的队列竟然还有些不清楚=。=)

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<stack>

using namespace std;

typedef  long long ll;
ll dp[20][20][3000];
int dis[20];

ll dfs(int len,int pov,int l,int lim)
{
if(l<0) return 0;
if(len<0) return l==0?1:0;
if(!lim&&dp[len][pov][l]!=-1) return dp[len][pov][l];
ll res=0;
int u=lim?dis[len]:9;
for(int i=0;i<=u;i++)
{
res+=dfs(len-1,pov,l+(len-pov)*i,lim&&i==u);
}
if(lim) return res;
else return dp[len][pov][l]=res;
}

ll solve(ll x)
{
int len=0;
while(x)
{
dis[len++]=x%10;
x/=10;
}
ll ans=0;
for(int i=0;i<len;i++)
ans+=dfs(len-1,i,0,1);
return ans-(len);
}

ll a,b;

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%I64d %I64d",&a,&b);
memset(dp,-1,sizeof(dp));
printf("%I64d\n",solve(b)-solve(a-1));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: