C题:A Water Problem(dp||搜索)
解法一:递归
#include<cstdio> #include<algorithm> using namespace std; long long n,x,y; long long solve(int m) { if(m==1) return x; if(m%2==1){ long long t1=solve(m+1); long long t2=solve(m-1); long long t3=n*x; return min(t3,min(t1,t2)+x); } long long t1=solve(m/2)+y; long long t2=m*x; return min(t1,t2); } int main() { while(scanf("%d%d%d",&n,&x,&y)!=EOF) printf("%lld\n",solve(n)); }
解法二:动态规划
#include<cstdio> #include<algorithm> using namespace std; const int maxn=1e7+10; int n,x,y; long long dp[maxn]; int main() { while(~scanf("%d%d%d",&n,&x,&y)){ dp[1]=x; for(int i=1;i<=n;i++){ if(i%2) dp[i]=min(dp[i/2+1]+x+y,dp[i-1]+x); else dp[i]=min(dp[i/2]+y,dp[i-1]+x); } printf("%lld\n",dp[n]); } }
(动态规划就是省略了搜索过程中的一些重复搜索的内容,而直接找到前后待搜索关键字的状态转移关系,和记忆化搜索还是略有区别的,因为记忆化搜索只是剪枝,并没有找到它们之间的关系)