您的位置:首页 > 其它

hdu5791Two dp hdu5781ATM Mechine 概率dp hdu5787 K-wolf Number 数位dp

2017-09-08 02:21 337 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5791

很水的dp,是考虑复杂了

考虑重复的转移方程

dp【i】【j】= dp【i-1】【j】+ dp【i】【j】- dp【i-1】【j-1】

#include<bits/stdc++.h>
using namespace std;
const int mo=1e9+7;
const int maxn=1005;
long long dp[maxn][maxn];
int a[maxn],b[maxn];
int main()
{
int n,m,i,j;
while(cin>>n>>m)
{
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=m;i++)
scanf("%d",&b[i]);

long long ans=0;
for(i=1;i<=n;i++)
{
long long temp=0;
for(j=1;j<=m;j++)
{
dp[i][j]=(dp[i-1][j]+temp)%mo;
if(a[i]==b[j])
{
dp[i][j]=(dp[i][j]+dp[i-1][j-1]+1)%mo;
temp=(temp+dp[i-1][j-1]+1)%mo;
}
}
}
cout<<dp
[m]<<endl;
}
return 0;
}


http://acm.hdu.edu.cn/showproblem.php?pid=5781

挺好的一个概率dp

题意:可能在银行存着0~k元,不可查询余额,若取多给予一次警告,取少取走,直到余额0,警告不可超过w次,若采取最优取钱策略,问取钱次数的期望。

赌你不敢写,因为会使用二分较优策略,所以警告次数不会很多

dp【j】【i】代表可能存在0~j元,还剩i次警告次数的取钱次数期望

#include<bits/stdc++.h>
#define eps 1e-9
#define PI 3.141592653589793
#define bs 1000000007
#define bsize 256
#define MEM(a) memset(a,0,sizeof(a))
typedef long long ll;
using namespace std;
double dp[2005][21];
void init()
{
double inf=1e9+11;
int i,j,k;
for(i=1;i<=2000;i++)
dp[i][0]=inf;
for(i=0;i<=20;i++)
dp[0][i]=0;
for(i=1;i<=20;i++)
{
for(j=1;j<=2000;j++)
{
double now=inf;
for(k=1;k<=j;k++)
{
now=min(now,dp[k-1][i-1]*k/(j+1)+dp[j-k][i]*(j-k+1)/(j+1));
}
dp[j][i]=now+1;
}
}
}
int main()
{
int k,w,i,j;
init();
while(cin>>k>>w)
{
w=min(w,20);
printf("%.6lf\n",dp[k][w]);
}
return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=5787

企图用一个十进制数表示状态,很明显没有办法区分  0012 和12(其实这里可以记录一个长度,不把12当作一个状态,因为长度4,所以也不会多dfs几次

于是很笨重的用了4个变量

#include<bits/stdc++.h>
using namespace
d630
std;
long long dp[11][11][11][11][22];
int mo,k;
int a[22];
long long dfs(int pos,int s[4],int limit,int lead)
{
if(pos==-1)
{
return !lead;
}
if(dp[s[0]][s[1]][s[2]][s[3]][pos]!=-1&&!limit&&!lead)
{
return dp[s[0]][s[1]][s[2]][s[3]][pos];
}
int book[11],t[5];
long long ans=0;
int up=limit?a[pos]:9;
memset(book,0,sizeof(book));
for(int i=0;i<4;i++)
{
t[i]=s[i];
}
for(int i=4-k+1;i<4;i++)
book[t[i]]=1;
for(int i=0;i<=up;i++)
{
s[0]=t[1],s[1]=t[2],s[2]=t[3];
if(book[i])
continue;
if(lead&&i==0)
s[3]=10;
else
s[3]=i;
ans+=dfs(pos-1,s,limit&&i==a[pos],lead&&i==0);
}
if(dp[t[0]][t[1]][t[2]][t[3]][pos]==-1&&!limit&&!lead)
dp[t[0]][t[1]][t[2]][t[3]][pos]=ans;
return ans;
}
long long solve(long long x)
{
int pos=0;
while(x)
{
a[pos++]=x%10;
x/=10;
}
int s[5];
for(int i=0;i<4;i++)
s[i]=10;
return dfs(pos-1,s,1,1);
}
int main()
{
long long l,r;
int i;
while(cin>>l>>r>>k)
{
memset(dp,-1,sizeof(dp));
printf("%lld\n",solve(r)-solve(l-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: