简单dp这东西主要是看你能不能把状态方程列好,列好之后十分简单,同时这也需要你能意识到题目的意思,一般要算方法数并且后一个状态可以由前一个状态得到,那么一般都是简单dp可以算出来的
说两个题目:
第一个题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1496
咋一看这不是数学组的题吗?比赛时没做出来,后来看了题解,原来如此,一个状态转移就行
设一个dp的二维数组,一个代表苹果数,一个代表是否已经吃到大于d的苹果
状态转移方程一共有三个:
1.如果已经吃到大于d的苹果
dp[当前苹果数][已吃到苹果]=(dp[当前苹果数-当前分支苹果数][已吃到苹果]+dp[当前苹果数][已吃到苹果])%mod;
2.没有吃到大于d的苹果,但是现在吃
dp[当前苹果数][已吃到苹果]=(dp[当前苹果数-当前分支苹果数][未吃到苹果]+dp[当前苹果数][已吃到苹果])%mod;
3.没吃到大于d的苹果,也不准备吃
dp[当前苹果数][未吃到苹果]=(dp[当前苹果数-当前分支苹果数][未吃到苹果]+dp[当前苹果数][未吃到苹果])%mod;
代码如下:
#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <stack>
#include <queue>
#include <sstream>
#include <vector>
#include <set>
using namespace std;
const int maxn=200;
const int mod=1e9+7;
int dp[maxn][2];
int main()
{
int n,k,d;
while(scanf("%d%d%d",&n,&k,&d)!=EOF)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k&&j<=i;j++)//苹果可以取得的数,正好可以用循环代替
{
dp[i][1]=(dp[i-j][1]+dp[i][1])%mod;
if(j>=d)
{
dp[i][1]=(dp[i-j][0]+dp[i][1])%mod;
}
else
{
dp[i][0]=(dp[i-j][0]+dp[i][0])%mod;
}
}
}
printf("%d\n",dp[n][1]);
}
return 0;
}
然后知道套路之后立马就A另一道题
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1496
这题有点坑,卡时间,并且还要注意除余后有可能出现的负数
也是三个转移方程,考虑到不能连续跳两次,所以也是两维的数组
第一个代表第几步,第二个代表是否已经跳过,这个自己看代码吧,不多说了
#include <iostream>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <stack>
#include <queue>
#include <sstream>
#include <vector>
#include <set>
using namespace std;
const int maxn=100005;
const int mod=1e9+7;
int dp[maxn][2],ans[maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1; i<=maxn; i++)
{
if(i>=m)
{
dp[i][1]=(dp[i-m][0]+dp[i][1])%mod;
}
dp[i][0]=(dp[i-1][0]+dp[i][0])%mod;
dp[i][0]=(dp[i-1][1]+dp[i][0])%mod;
}
ans[0]=0;
for(int i=1;i<=maxn;i++)
{
ans[i]=(ans[i-1]+dp[i][1]+dp[i][0])%mod;
}
while(n--)
{
int l,r;
scanf("%d%d",&l,&r);
if(ans[r]>ans[l-1])
printf("%d\n",ans[r]-ans[l-1]);
else
printf("%d\n",ans[r]+mod-ans[l-1]);
}
return 0;
}