打卡信奥刷题(1794)用C++信奥 P8838 [传智杯 #3 决赛] 面试

P8838 [传智杯 #3 决赛] 面试

题目背景

disangan233 和 disangan333 去面试了,面试官给了一个问题,热心的你能帮帮他们吗?

题目描述

现在有 nnn 个服务器,服务器 iii 最多能处理 aia_iai 大小的数据。

接下来会有 kkk 条指令 bkb_kbk,指令 iii 表示发送 bib_ibi 的数据,需要你分配一个空闲的服务器。

请你算出一个序列 pkp_kpk 表示指令 iii 的数据分配给服务器 pip_ipi,且 pkp_kpk 的字典序最小;如果无法分配,输出 “-1”。

对于所有数据,n,k≤6n,k\leq 6n,k6ai,bi≤10a_i,b_i \leq 10ai,bi10

输入格式

输入共 333 行。

111 行输入 222 个正整数 n,kn,kn,k

222 行输入 nnn 个正整数 aia_iai,表示服务器 iii 最多能处理的数据大小。

333 行输入 kkk 个正整数 bib_ibi,表示指令 iii

输出格式

输出共 111kkk 个正整数 p1…pkp_1\ldots p_kp1pk,或者输出 “-1”。

输入输出样例 #1

输入 #1

6 6
1 9 1 9 8 1
1 1 4 5 1 4

输出 #1

1 3 2 4 6 5

说明/提示

样例解释

第 1 条指令分给服务器 1;
第 2 条指令分给服务器 3;
第 3 条指令分给服务器 2;
第 4 条指令分给服务器 4;
第 5 条指令分给服务器 6;
第 6 条指令分给服务器 5。

C++实现

#include<bits/stdc++.h>
using namespace std;
int n,k,a[7],b[7],p[7];
bool f=1,u[7];
void dfs(int s){
    if(s==k+1){
        if(f)
            for(int i=1;i<=n;i++)
                printf("%d ",p[i]);
        f=0;
        return;
    }
    for(int i=1;i<=n;i++)
        if(a[i]-b[s]>=0 &&!u[i]){
            p[s]=i,u[i]=1;
            dfs(s+1);
            u[i]=0;
        }
    return;
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",a+i);
    for(int i=1;i<=k;i++)
        scanf("%d",b+i);
    dfs(1);
    if(f)
        puts("-1");
    return 0;
}

在这里插入图片描述

后续:

接下来我会不断用C++来实现信奥比赛中的算法题、C++考级编程题实现、白名单赛事考题实现,感兴趣的请关注,我后续将继续分享相关内容

### 关于 P6464 #2 决赛 送门 树形动态规划 #### 背景描述 目涉及 n 座教学楼以及 m 条连接这些教学楼的双向道路,形成了一张无向图。目标是在这张图上执行特定的操作并求得最优解。 #### 解决方案概述 对于此类问,通常采用树形动态规划 (Tree DP) 方法来解决。该方法适用于具有层次结构的数据集,在本案例中即为由教学楼构成的网络拓扑结构[^1]。 #### 动态规划状态定义 设 `f[u][i]` 表示以节点 u 作为根结点的子树内选择了 i 所能获得的最大价值,则可以建立如下转移方程: ```cpp for each child v of node u { for j from size[v] downto 0 { // 反向枚举防止重复计算 f[u][j + k] = max(f[u][j + k], f[u][j] + f[v][k]); } } ``` 这里假设已知所有孩子节点的状态,并通过上述方式更新父节点的状态。其中 `size[]` 数组记录各棵子树大小以便控制循环边界。 #### 边界条件处理 初始化时需考虑叶子节点的情况,一般设定其初始值为零或其他适当常数,具体取决于实际问需求。另外还需注意特判仅有单个顶点的情形。 #### 复杂度分析 由于每次访问每条边两次(一次正向一次反向),因此时间复杂度大致为 O(n),这使得算法能够在合理时间内完成较大规模输入实例的运算。 #### 实现细节提示 - 使用邻接表存储图的息; - 运用深度优先搜索遍历整棵树; - 记录每个节点及其对应子树内的最佳选择情况。 ```cpp #include <bits/stdc++.h> using namespace std; const int N = ...; vector<int> adj[N]; int dp[N]; void dfs(int u, int parent){ for(auto &v : adj[u]){ if(v != parent){ dfs(v, u); // 更新当前节点u的最佳决策 } } } int main(){ cin >> n >> m; while(m--){ int a,b; cin>>a>>b; adj[a].push_back(b); adj[b].push_back(a); } memset(dp, 0, sizeof(dp)); dfs(1,-1); // 假定第一个节点为根 cout << "最终结果:" << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值