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;
}