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

来源:互联网 发布:me的域名 编辑:程序博客网 时间:2024/05/19 13:23

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[n][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 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;}