CF864E:E. Fire(01背包 & 路径输出)

本文介绍了一种在火灾场景下,如何最大化救援物品价值的算法。通过动态规划的方法,在考虑物品救援时间和燃烧时限的情况下,确定最优救援顺序。

E. Fire
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable items. Polycarp estimated that it would take tiseconds to save i-th item. In addition, for each item, he estimated the value of di — the moment after which the item i will be completely burned and will no longer be valuable for him at all. In particular, if ti ≥ di, then i-th item cannot be saved.

Given the values pi for each of the items, find a set of items that Polycarp can save such that the total value of this items is maximum possible. Polycarp saves the items one after another. For example, if he takes item a first, and then item b, then the item a will be saved in ta seconds, and the item b — in ta + tb seconds after fire started.

Input

The first line contains a single integer n (1 ≤ n ≤ 100) — the number of items in Polycarp's house.

Each of the following n lines contains three integers ti, di, pi (1 ≤ ti ≤ 201 ≤ di ≤ 2 0001 ≤ pi ≤ 20) — the time needed to save the item i, the time after which the item i will burn completely and the value of item i.

Output

In the first line print the maximum possible total value of the set of saved items. In the second line print one integer m — the number of items in the desired set. In the third line print m distinct integers — numbers of the saved items in the order Polycarp saves them. Items are 1-indexed in the same order in which they appear in the input. If there are several answers, print any of them.

Examples
input
3
3 7 4
2 6 5
3 7 6
output
11
2
2 3 
input
2
5 6 1
3 3 5
output
1
1
1 
Note

In the first example Polycarp will have time to save any two items, but in order to maximize the total value of the saved items, he must save the second and the third item. For example, he can firstly save the third item in 3 seconds, and then save the second item in another 2seconds. Thus, the total value of the saved items will be 6 + 5 = 11.

In the second example Polycarp can save only the first item, since even if he immediately starts saving the second item, he can save it in 3seconds, but this item will already be completely burned by this time.


题意:火灾时有N件物品可以救出,每一件有三个值a,b,c,表示需要救它要a时间,且在b时间该物品就立刻烧毁,c为它的价值,问最多可以救出多少价值,并输出救的顺序。

思路:明显的背包dp,由于本题有“b”属性的限制,b小的物品不能从b大的状态转移过来,于是需要对b排序,先处理b小的物品。路径输出的话范围小可以用vector直接搞,也可以用数组标记一下。

# include <iostream>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
using namespace std;
const int maxn = 2003;
int a[maxn], b[maxn], c[maxn], dp[maxn];
int id[maxn];
vector<int>v[maxn];
bool cmp(int x, int y)
{
    return b[x] < b[y];
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; ++i)
        scanf("%d%d%d",&a[i],&b[i],&c[i]),id[i] = i;
    sort(id, id+n, cmp);
    for(int k=0; k<n; ++k)
    {
        int i = id[k];
        if(a[i]>=b[i]) continue;
        for(int j=b[i]-1; j>=a[i]; --j)
        {
            if(dp[j-a[i]]+c[i] > dp[j])
            {
                dp[j] = dp[j-a[i]]+c[i];
                v[j].clear();
                v[j] = v[j-a[i]];
                v[j].emplace_back(i);
            }
        }
    }
    int imax=0, num;
    for(int i=0; i<=2000;++i)
        if(dp[i] > imax)
            imax = dp[i], num=i;
    printf("%d\n",imax);
    printf("%d\n",v[num].size());
    for(auto i : v[num])
        printf("%d ",i+1);
    return 0;
}


# include <iostream>
# include <cstdio>
# include <cstring>
# include <stack>
# include <algorithm>
using namespace std;
const int maxn = 2003;
int a[maxn], b[maxn], c[maxn], dp[maxn];
int id[maxn], cho[maxn], way[103][maxn];
bool cmp(int x, int y)
{
    return b[x] < b[y];
}
int main()
{
    int n, imax, ans=0, num;
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
        scanf("%d%d%d",&a[i],&b[i],&c[i]),id[i] = i;
    sort(id+1, id+n+1, cmp);
    for(int k=1; k<=n; ++k)
    {
        int i = id[k];
        if(a[i]>=b[i]) continue;
        for(int j=b[i]-1; j>=a[i]; --j)
        {
            if(dp[j-a[i]]+c[i] > dp[j])
            {
                dp[j] = dp[j-a[i]]+c[i];
                cho[j] = i;
                way[i][j] = cho[j-a[i]];
            }
            if(dp[j] > ans)
            {
                ans = dp[j];
                imax = j;
                num = i;
            }
        }
    }
    printf("%d\n",ans);
    if(ans == 0) return 0*puts("0");
    stack<int>st;
    while(imax && num)
    {
        st.push(num);
        int tmp = imax;
        imax -= a[num];
        num = way[num][tmp];
    }
    printf("%d\n",st.size());
    while(!st.empty())
    {
        printf("%d ",st.top());
        st.pop();
    }
    return 0;
}


[2025/10/29 16:49:34.635 GMT+08:00] Step 1/9 : FROM registry-cbu.huawei.com/fuxi-build-plus/euler29_x86_jdk11:latest [2025/10/29 16:49:34.635 GMT+08:00] ---&gt; c66daa552bfd [2025/10/29 16:49:34.635 GMT+08:00] Step 2/9 : COPY target/*.jar ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; ef2343b1f665 [2025/10/29 16:49:35.376 GMT+08:00] Step 3/9 : COPY result.json ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; beb95c94e068 [2025/10/29 16:49:35.376 GMT+08:00] Step 4/9 : COPY start.sh ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; df7270ab7c70 [2025/10/29 16:49:35.376 GMT+08:00] Step 5/9 : COPY stop.sh ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; e29ea0c91863 [2025/10/29 16:49:35.376 GMT+08:00] Step 6/9 : COPY pid.file ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; 35d0b7a33e8a [2025/10/29 16:49:35.376 GMT+08:00] Step 7/9 : COPY app.log ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; 86bea2e9210b [2025/10/29 16:49:35.376 GMT+08:00] Step 8/9 : COPY requirements.txt ./ [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; a3e7e22e89dc [2025/10/29 16:49:35.376 GMT+08:00] Step 9/9 : RUN chown service:servicegroup ./*.sh &amp;&amp; chmod 740 ./*.sh &amp;&amp; chown service:servicegroup requirements.txt &amp;&amp; chmod 640 requirements.txt &amp;&amp; chown service:servicegroup target/*.jar &amp;&amp; chmod 740 target/*.jar &amp;&amp; chown service:servicegroup result.json &amp;&amp; chmod 740 result.json &amp;&amp; chown service:servicegroup pid.file &amp;&amp; chmod 740 pid.file &amp;&amp; chown service:servicegroup app.log &amp;&amp; chmod 740 app.log &amp;&amp; mkdir -p /msg &amp;&amp; chown service:servicegroup /msg [2025/10/29 16:49:35.376 GMT+08:00] ---&gt; Running in 335df50cf3e9 [2025/10/29 16:49:35.376 GMT+08:00] [91mchown: cannot access &#39;target/*.jar&#39;: No such file or directory
最新发布
10-30
&lt;think&gt;我们正在解决Docker构建过程中出现的&ldquo;chown: cannot access &#39;target/*.jar&#39;: No such file or directory&rdquo;错误。这个错误通常发生在Dockerfile中尝试更改文件所有权时,但指定的文件或目录不存在。以下是逐步的解决方案: ### 1. **确认构建上下文和文件存在** - 确保在运行`docker build`命令时,构建上下文包含了`target`目录以及所需的JAR文件。 - 在构建之前,确保在本地已经成功构建了项目(例如使用Maven或Gradle),并且`target`目录下生成了预期的JAR文件。 ### 2. **检查Dockerfile中的路径** - 错误信息表明Dockerfile中有一条命令尝试访问`target/*.jar`,但该路径在Docker构建上下文中不存在。 - 检查Dockerfile中涉及`target/*.jar`的命令,例如: ```dockerfile COPY target/*.jar app.jar RUN chown -R user:user /app # 示例命令,可能与此相关 ``` 或者直接: ```dockerfile RUN chown user:user target/*.jar # 错误可能发生在这里 ``` - 注意:在Docker构建过程中,工作目录可能与预期不同。如果使用`COPY`或`ADD`指令复制文件,需要确保源路径正确,且目标路径在容器内存在。 ### 3. **使用具体的文件名(避免通配符)** - 如果可能,尽量避免在`COPY`或`ADD`中使用通配符(特别是当只有一个JAR文件时)。可以明确指定文件名,例如: ```dockerfile COPY target/myapp-1.0.0.jar app.jar ``` 这样更明确,且避免因通配符匹配不到文件而失败。 ### 4. **确保文件被正确复制** - 在`chown`命令之前,确保已经通过`COPY`或`ADD`将文件复制到容器中。例如: ```dockerfile COPY target/*.jar /app/ WORKDIR /app RUN chown -R user:user *.jar # 现在文件在/app目录下 ``` 或者,如果在复制后文件位于容器内的指定位置,那么`chown`操作应该在复制后的路径上进行。 ### 5. **使用多阶段构建(如果适用)** - 如果是在多阶段构建中,确保前一阶段已经将文件复制到当前阶段,并且路径正确。例如: ```dockerfile FROM maven:3.8.4 AS build WORKDIR /app COPY . . RUN mvn package FROM openjdk:11 COPY --from=build /app/target/*.jar /app.jar RUN chown user:user /app.jar # 这里操作的文件是/app.jar ``` ### 6. **检查.dockerignore文件** - 如果项目中有`.dockerignore`文件,确保它没有排除`target`目录或生成的JAR文件。否则,在构建时这些文件不会被包含在上下文中。 ### 7. **调试Docker构建** - 如果仍然不确定,可以尝试在Dockerfile中增加调试步骤,例如在复制后列出目录内容: ```dockerfile RUN ls -lR /target # 或相应的路径 ``` 这样可以查看文件是否被正确复制到镜像中。 ### 示例Dockerfile修正 假设原始Dockerfile如下(其中包含错误): ```dockerfile FROM openjdk:11 COPY target/*.jar app.jar RUN chown nobody:nobody app.jar # 这里可能出错,因为如果COPY失败,app.jar就不存在 ENTRYPOINT [&quot;java&quot;,&quot;-jar&quot;,&quot;app.jar&quot;] ``` 修正为(确保COPY成功后再执行chown): ```dockerfile FROM openjdk:11 # 先复制文件,并指定为目标名称 COPY target/*.jar /app.jar # 然后更改所有权(如果确实需要,否则可以省略,因为默认是root) RUN chown nobody:nobody /app.jar USER nobody ENTRYPOINT [&quot;java&quot;,&quot;-jar&quot;,&quot;/app.jar&quot;] ``` 但注意:如果`target`目录下有多个JAR文件,`COPY target/*.jar /app.jar`会失败(因为不能复制多个文件到单个文件)。此时需要处理多个JAR文件的情况,或者确保只有一个JAR文件。 ### 8. **处理多个JAR文件的情况** - 如果`target`目录中可能有多个JAR文件,但只需要一个,可以使用更精确的通配符(例如项目的主要JAR文件)或通过构建脚本确定具体的文件名。 - 或者,复制整个目录并更改所有权: ```dockerfile COPY target/*.jar /app/ RUN chown -R nobody:nobody /app ``` ### 总结 此错误的核心是Docker构建过程中无法找到`target/*.jar`文件。请按照上述步骤检查并修正Dockerfile,确保文件在构建上下文中存在,并在容器内被正确复制和引用。 &sect;&sect;相关问题&sect;&sect; 1. 如何优化Dockerfile以减少构建时间和镜像大小? 2. 在Docker构建中如何处理动态生成的文件(如编译后的JAR)? 3. Dockerfile中COPY和ADD指令有什么区别? &lt;/think&gt;### Docker构建时出现 `chown: cannot access &#39;target/*.jar&#39;: No such file or directory` 的解决方案 此错误通常发生在 Dockerfile 中尝试操作文件时,文件路径不存在或构建上下文未正确包含文件。以下是逐步解决方法: --- #### 1. **验证文件路径是否存在** - **在本地构建项目**:确保在运行 `docker build` 前已生成 JAR 文件: ```bash mvn clean package # Maven项目 # 或 gradle build # Gradle项目 ``` - **检查 `target` 目录**:确认 `target/` 下有 JAR 文件(如 `target/your-app.jar`)。 --- #### 2. **修正 Dockerfile 中的路径** - **问题根源**:通配符 `*.jar` 在 COPY 指令中可能无法解析或路径错误。 - **解决方案**: ```dockerfile # 明确指定文件名(推荐) COPY target/your-app-name.jar /app/app.jar # 或使用精确路径(避免通配符) COPY target/ /app/target/ RUN chown -R user:group /app/target/*.jar ``` --- #### 3. **检查构建上下文** - Docker 仅能访问 `docker build` 指定的目录中的文件: ```bash # 确保在项目根目录(含 target/)执行构建 docker build -t my-image . ``` - **避免范围过大**:若项目根目录有大量文件,使用 `.dockerignore` 排除无关文件。 --- #### 4. **多阶段构建优化** 适用于复杂项目,避免依赖宿主机文件: ```dockerfile # 第一阶段:构建JAR FROM maven:3.8-openjdk-11 AS builder WORKDIR /build COPY . . RUN mvn package # 第二阶段:运行 FROM openjdk:11 COPY --from=builder /build/target/*.jar /app.jar # 此处路径在镜像内 USER nonrootuser # 无需单独chown ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;/app.jar&quot;] ``` --- #### 5. **其他排查点** - **`.dockerignore` 文件**:确保未排除 `target/` 目录。 - **权问题**:添加 `USER` 指令避免权操作: ```dockerfile USER 1001:1001 # 使用非root用户 COPY target/app.jar /app.jar ``` - **调试命令**:在 Dockerfile 中添加检查步骤: ```dockerfile RUN ls -l /target # 验证文件是否存在 ``` --- ### 关键总结 | **步骤** | **操作** | |------------------------|-------------------------------------------------------------------------| | 1. 本地生成 JAR 文件 | 执行 `mvn package` 或 `gradle build` | | 2. 修正 Dockerfile 路径 | 使用具体文件名代替 `*.jar`,或复制整个目录 | | 3. 检查构建上下文 | 在含 `target/` 的目录执行 `docker build` | | 4. 多阶段构建(可选) | 在 Docker 内部完成编译,避免依赖宿主机文件 | &gt; 通过以上步骤,95% 的此类错误可被解决。若问题仍存在,需检查构建日志中 `COPY` 指令是否成功复制文件[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值