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
",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
",dp[n]);    
    }
}

(动态规划就是省略了搜索过程中的一些重复搜索的内容,而直接找到前后待搜索关键字的状态转移关系,和记忆化搜索还是略有区别的,因为记忆化搜索只是剪枝,并没有找到它们之间的关系)

原文地址:https://www.cnblogs.com/freinds/p/6544595.html