槑先生 2021-08-03 11:27 采纳率: 70%
浏览 118
已结题

关于C++动态规划,请问代码bug在哪儿?

这道问题起源洛谷

img

img

我用动态规划来写,solve(i,j)表示第 i 次调音调到 j 可不可行,true代表可行,false代表不可行
那么i>1时,solve(i,j)=true当且仅当 0<=j - a[j]<=maxlevel && solve(i - 1, j - a[j]) == true
或 0<=j +a[j]<=maxlevel && solve(i - 1, j +a[j]) == true
以下是我用这个思路写的代码

#include<iostream>
using namespace std;

int n, bl, ml;
int a[51];

bool in(int n) {
    if (n >= 0 && n <= ml) {
        return true;
    }
    else {
        return false;
    }
}
bool solve(int i, int j) {
        if (i == 0) {
            if (j == bl) {                
                return true;
            }
            else {                
                return false;
            }
        }
        else{
            if (in(j - a[j]) == true && (solve(i - 1, j - a[j]) == true)) {                
                return true;
            }
            else if (in(j + a[j]) == true && (solve(i - 1, j + a[j]) == true)) {                
                return true;
            }
            else {                
                return false;
            }
        }
    
}

int main() {
    cin >> n >> bl >> ml;
    for (int i = 1;i <= n;i++) {
        cin >> a[i];
    }    
    for (int j = ml;j >= -1;j--) {
        bool ans2 = solve(n, j);
        if (ans2 == true) {
            cout << j;
            break;
        }
        if (j == -1) {
            cout << -1;
        }        
    }
}



但是程序好像有bug,输入样例不对

img

请问bug在哪儿?

  • 写回答

3条回答 默认 最新

  • StjpStjp 2021-08-05 13:52
    关注

    动态规划的背包问题。

    但是如果把这道题强行理解为01背包未免有些和01背包的概念不符,其实这道题是到达性的01背包。

    我们可以不把这道题想象的那么复杂,直接按照最基础的动态规划来,设置动态转移方程和初值。

    这回我们用标记数组来动归。

    设状态转移方程f[i][j]为第i首歌能否达到j的音量,能为1,不能为0。

    这样的话我们就可以开始动归,最后只需要枚举出最大的f[n][i],就是需要找的答案了。

    这里还需要注意,初值f[0][begin]要设置为1,因为没开始之前就可以达到begin的音量。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,beginlevel,maxlevel;
    int c[60];
    int f[60][1010];
    int main()
    {
        scanf("%d%d%d",&n,&beginlevel,&maxlevel);
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        f[0][beginlevel]=1;
        for(int i=1;i<=n;i++)
            for(int j=maxlevel;j>=0;j--)
            {
                if(f[i-1][j] && j+c[i]<=maxlevel)
                    f[i][j+c[i]]=1;
                if(f[i-1][j] && j-c[i]>=0)
                    f[i][j-c[i]]=1;
            }
        for(int i=maxlevel;i>=0;i--)
            if(f[n][i]==1)
            {
                printf("%d",i);
                return 0;
            }
        printf("-1");
        return 0;
    }
    
    
    

    DFS也行

    #include<bits/stdc++.h>
    #define ll long long
    #define reg register
    using namespace std;
    int bl,ml,ans,c[55],n;
    bool f[51][1010];//定义t是否能达到k的音量
    void dfs(int t,int k){
        if(k<0||k>ml)return;
        //剪枝部分↓
        if(f[t][k])return;
        //如果改点已经有了
        //就不要再搜了
        else f[t][k]=1;//否则算他访问过了
        //剪枝部分↑
        if(t==n){
            ans=max(ans,k);
            return;
        }
        dfs(t+1,k+c[t+1]);
        dfs(t+1,k-c[t+1]);
    }
    int main(){
        ans=-1;
        scanf("%d%d%d",&n,&bl,&ml);
        for(reg int i=1;i<=n;++i){
            scanf("%d",&c[i]);
        }
        dfs(0,bl);
        cout<<ans;
        return 0; 
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 8月13日
  • 已采纳回答 8月5日
  • 创建了问题 8月3日

悬赏问题

  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行