10 1 0 0 0 10 1 2 3 4 5 6
15
卡了两天了。。倒是一看就是dp可解,大体状态也表示好了,但死活没推出状态转移方程。看了一下标程,顿感自己萨比了。。
dp[i][j] 代表跳j次可以到达i处(i为数组下标) 可得
dp[i][j]=max(dp[i][j],dp[i-k][j-1])(k∈[1,min(i,5)]);注意边界。。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <set> #include <cmath> #include <map> #include <stack> #define ll long long using namespace std; const int INF=0x3f3f3f3f; int n,k,a[110],dp[110][55]; int main() { while(scanf("%d%d",&n,&k)!=EOF) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i][0]=a[i]; } for(int i=1;i<=n;i++) { for(int j=1;j<=min(i,5);j++) { for(int tk=1;tk<=k;tk++) dp[i][tk]=max(dp[i][tk],dp[i-j][tk-1]+a[i]); } } int ans=-INF; for(int i=1;i<=n;i++) ans=max(ans,dp[i][k]); printf("%d\n",ans); } return 0; }看了标程写的记忆化搜索,感觉记忆化也没那么神秘了,以前从来没了解过QAQ。。我的理解是:找出状态数组,当你推不出来状态转移方程的时候,记忆化搜索或许不失为一种解决方案。前提是要有把搜索过程中的数据保存起来的思想,盲目的暴搜是不能解决问题的。。会T到没盆友的我深有体会。。#include <iostream> #include <cstdio> #include <algorithm> #include <set> #include <cctype> #include <cstring> #include <string> #include <vector> #include <stack> #include <queue> using namespace std; #define ll long long const int maxn=110; const int INF=0x3f3f3f3f; int a[maxn],n,kk,tem,ans; int dp[maxn][55]; int dfs(int s,int k) { if(dp[s][k]!=-1) return dp[s][k]; dp[s][k]=a[s]; int tem=0; if(k) { for(int i=1;i<=5&&i+s<n;i++) tem=max(tem,dfs(i+s,k-1)); } dp[s][k]+=tem; return dp[s][k]; } int main() { while(scanf("%d%d",&n,&kk)!=EOF) { memset(dp,-1,sizeof(dp)); for(int i=0;i<n;i++) scanf("%d",a+i); ans=-INF; for(int i=0;i<n;i++) { ans=max(dfs(i,kk),ans); } printf("%d\n",ans); } return 0; }
</pre><pre>
原文地址:http://blog.csdn.net/qq_16255321/article/details/40709567