当前位置: 首页 > news >正文

Codeforces Global Round 19 D题 Yet Another Minimization Problem(推式子,01背包变形)

题目链接

https://codeforces.com/problemset/problem/1637/D

思路

对于原式子进行推导

∑ i = 1 n ∑ j = i + 1 n ( a i + a j ) 2 + ∑ i = 1 n ∑ j = i + 1 n ( b i + b j ) 2 \sum_{i=1}^{n} \sum_{j=i+1}^{n}(a_{i}+ a_{j})^{2} + \sum_{i=1}^{n} \sum_{j=i+1}^{n}(b_{i}+ b_{j})^{2} i=1nj=i+1n(ai+aj)2+i=1nj=i+1n(bi+bj)2

= = = ∑ i = 1 n ∑ j = i + 1 n ( a i 2 + a j 2 + b i 2 + b j 2 ) + ∑ i = 1 n ∑ j = i + 1 n ( 2 × ( a i a j + b i b j ) ) \sum_{i=1}^{n} \sum_{j=i+1}^{n}(a_{i}^{2}+ a_{j}^{2}+b_{i}^{2}+b_{j}^{2}) + \sum_{i=1}^{n} \sum_{j=i+1}^{n}(2 \times (a_{i}a_{j}+b_{i}b_{j})) i=1nj=i+1n(ai2+aj2+bi2+bj2)+i=1nj=i+1n(2×(aiaj+bibj))

可以发现, ∑ i = 1 n ∑ j = i + 1 n ( a i 2 + a j 2 + b i 2 + b j 2 ) \sum_{i=1}^{n} \sum_{j=i+1}^{n}(a_{i}^{2}+ a_{j}^{2}+b_{i}^{2}+b_{j}^{2}) i=1nj=i+1n(ai2+aj2+bi2+bj2)是一个定值,我们只需要计算 ∑ i = 1 n ∑ j = i + 1 n ( 2 × ( a i a j + b i b j ) ) \sum_{i=1}^{n} \sum_{j=i+1}^{n}(2 \times (a_{i}a_{j}+b_{i}b_{j})) i=1nj=i+1n(2×(aiaj+bibj))的最小值即可。

我们定义 s u m [ i ] = ∑ j = 1 i a j + ∑ j = 1 i b j sum[i] = \sum_{j=1}^{i} a_{j} + \sum_{j=1}^{i} b_{j} sum[i]=j=1iaj+j=1ibj

考虑使用 d p dp dp。我们定义 d p [ i ] [ j ] dp[i][j] dp[i][j]表示只考虑前 i i i位时, a a a数组的背包容量为 j j j时的最小值。(先不考虑系数 2 2 2,因此最后的结果为答案的一半)。

若不交换 a i a_{i} ai b i b_{i} bi,则状态转移方程为:

d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i − 1 ] [ j − a [ i ] ] + a [ i ] ∗ ( j − a [ i ] ) + b [ i ] ∗ ( s u m [ i − 1 ] − j + a [ i ] ) ) dp[i][j] = min(dp[i][j], dp[i - 1][j - a[i]] + a[i] * (j - a[i]) + b[i] * (sum[i - 1] - j + a[i])) dp[i][j]=min(dp[i][j],dp[i1][ja[i]]+a[i](ja[i])+b[i](sum[i1]j+a[i]))

若交换 a i a_{i} ai b i b_{i} bi,则状态转移方程为:

d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i − 1 ] [ j − b [ i ] ] + b [ i ] ∗ ( j − b [ i ] ) + a [ i ] ∗ ( s u m [ i − 1 ] − j + b [ i ] ) ) dp[i][j] = min(dp[i][j], dp[i - 1][j - b[i]] + b[i] * (j - b[i]) + a[i] * (sum[i - 1] - j + b[i])) dp[i][j]=min(dp[i][j],dp[i1][jb[i]]+b[i](jb[i])+a[i](sum[i1]j+b[i]))

最终的答案即为: ∑ i = 1 n ∑ j = i + 1 n ( a i 2 + a j 2 + b i 2 + b j 2 ) \sum_{i=1}^{n} \sum_{j=i+1}^{n}(a_{i}^{2}+ a_{j}^{2}+b_{i}^{2}+b_{j}^{2}) i=1nj=i+1n(ai2+aj2+bi2+bj2) + + + m i n i = 1 m a x d p n , i min_{i=1}^{max}dp_{n,i} mini=1maxdpn,i

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e2 + 5, M = 1e4 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
int a[N], b[N], sum[N], dp[N][M];
void solve()
{cin >> n;for (int i = 1; i <= n; i++){cin >> a[i];}for (int i = 1; i <= n; i++){cin >> b[i];}int ans = 0;for (int i = 1; i < n; i++){for (int j = i + 1; j <= n; j++){ans += (pow(a[i], 2) + pow(a[j], 2));ans += (pow(b[i], 2) + pow(b[j], 2));}}for (int i = 1; i <= n; i++){sum[i] = sum[i - 1] + a[i] + b[i];}for (int i = 1; i <= n; i++){for (int j = 0; j <= 1e4; j++){dp[i][j] = inf;}}dp[0][0] = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= 1e4; j++){if (j >= a[i] && (sum[i - 1] - j + a[i]) >= 0)dp[i][j] = min(dp[i][j], dp[i - 1][j - a[i]] + a[i] * (j - a[i]) + b[i] * (sum[i - 1] - j + a[i]));if (j >= b[i] && (sum[i - 1] - j + b[i]) >= 0)dp[i][j] = min(dp[i][j], dp[i - 1][j - b[i]] + b[i] * (j - b[i]) + a[i] * (sum[i - 1] - j + b[i]));}}int res = inf;for (int i = 1; i <= 1e4; i++)res = min(res, dp[n][i]);cout << ans + res * 2 << endl;}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

http://www.mrgr.cn/news/35483.html

相关文章:

  • 模拟哈希表
  • LVGL第一篇-了解lvgl显示原理以及使用C++移植
  • Zookeeper
  • BERT训练环节(代码实现)
  • Seata分布式事务实践
  • Allegro视频去除走线的小方块
  • [linux][证书]证书导出公钥
  • 关于Python升级以后脚本不能运行的问题
  • LCR 028
  • 字符串哈希
  • 2-102基于matlab的蒙特卡洛仿真
  • 考研数据结构——C语言实现小顶堆
  • SpringBoot基础知识
  • string 的介绍及使用
  • C++语言桌面应用开发GTK3 Gtkmm3 Glade
  • 在Java中如何利用ClassLoader动态加密、解密Class文件
  • 面经宝典【1】-拼多多
  • 插入、更新与删除MySQL记录
  • Python 入门教程(7)面向对象 | 7.5、继承
  • Docker部署服务:快速入门指南