C#,动态规划的集合划分问题(DP Partition problem)算法与源代码

动态规划问题中的划分问题

动态规划问题中的划分问题是确定一个给定的集是否可以划分为两个子集,使得两个子集中的元素之和相同。

动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果。

2 应用示例


动态规划问题中的划分问题示例:
arr[]={1,5,11,5}
输出:真
数组可以划分为{1、5、5}和{11}
arr[]={1,5,3}
输出:false
数组不能划分为等和集。
以下是解决此问题的两个主要步骤:
1) 计算数组的和。如果sum为奇数,则不可能有两个sum相等的子集,因此返回false。
2) 如果数组元素之和为偶数,则计算sum/2并找到sum等于sum/2的数组子集。
第一步很简单。第二步很关键,可以使用递归或动态规划来解决。
递归解决方案
下面是上面提到的第二步的递归属性。
让isSubsetSum(arr,n,sum/2)为函数,如果
有一个子集arr[0..n-1],其和等于和/2isSubsetSum问题可分为两个子问题
a) IsubSetSum()不考虑最后一个元素(将n减至n-1)
b) isSubsetSum考虑最后一个元素(通过arr[n-1]和n到n-1减少sum/2)
如果上述任何子问题返回true,则返回true。
isSubsetSum(arr,n,sum/2)=isSubsetSum(arr,n-1,sum/2)|| isSubsetSum(arr,n-1,sum/2-arr[n-1])

3 源代码

using System;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public static partial class Algorithm_Gallery{#region 算法1private static bool Partition_Problem_IsSubset_Sum(int[] arr, int n, int sum){if (sum == 0){return true;}if (n == 0 && sum != 0){return false;}if (arr[n - 1] > sum){return Partition_Problem_IsSubset_Sum(arr, n - 1, sum);}return Partition_Problem_IsSubset_Sum(arr, n - 1, sum) || Partition_Problem_IsSubset_Sum(arr, n - 1, sum - arr[n - 1]);}static bool Partition_Problem_Solve(int[] arr, int n){int sum = 0;for (int i = 0; i < n; i++){sum += arr[i];}if (sum % 2 != 0){return false;}return Partition_Problem_IsSubset_Sum(arr, n, sum / 2);}#endregion#region 算法2private static bool Partition_Problem_IsSubset_Sum(int[] arr, int n, int sum, int[,] dp){if (sum == 0){return true;}if (n == 0 && sum != 0){return false;}if (dp[n, sum] != -1){return true;}if (arr[n - 1] > sum){return Partition_Problem_IsSubset_Sum(arr, n - 1, sum, dp);}dp[n, sum] = (Partition_Problem_IsSubset_Sum(arr, n - 1, sum, dp) || Partition_Problem_IsSubset_Sum(arr, n - 1, sum - arr[n - 1], dp)) ? 1 : -1;return dp[n, sum] > 0;}public static bool Partition_Problem_Solve_Second(int[] arr, int n){int sum = 0;for (int i = 0; i < n; i++){sum += arr[i];}if (sum % 2 != 0){return false;}int[,] dp = new int[n + 1, sum + 1];return Partition_Problem_IsSubset_Sum(arr, n, sum / 2, dp);}#endregion#region 算法3public static bool Partition_Problem_Solve_Third(int[] arr, int n){int sum = 0;for (int i = 0; i < n; i++){sum += arr[i];}if (sum % 2 != 0){return false;}bool[,] part = new bool[sum / 2 + 1, n + 1];for (int i = 0; i <= n; i++){part[0, i] = true;}for (int i = 1; i <= sum / 2; i++){part[i, 0] = false;}for (int i = 1; i <= sum / 2; i++){for (int j = 1; j <= n; j++){part[i, j] = part[i, j - 1];if (i >= arr[j - 1]){part[i, j] = part[i, j - 1] || part[i - arr[j - 1], j - 1];}}}return part[sum / 2, n];}#endregion#region 算法4public static bool Partition_Problem_Solve_Fourth(int[] arr, int n){int sum = 0;for (int i = 0; i < n; i++){sum += arr[i];}if (sum % 2 != 0){return false;}bool[] part = new bool[sum / 2 + 1];for (int i = 0; i <= sum / 2; i++){part[i] = false;}for (int i = 0; i < n; i++){for (int j = sum / 2; j >= arr[i]; j--){if (part[j - arr[i]] == true || j == arr[i]){part[j] = true;}}}return part[sum / 2];}#endregion}
}

4 源程序

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    public static partial class Algorithm_Gallery
    {
        #region 算法1
        private static bool Partition_Problem_IsSubset_Sum(int[] arr, int n, int sum)
        {
            if (sum == 0)
            {
                return true;
            }
            if (n == 0 && sum != 0)
            {
                return false;
            }
            if (arr[n - 1] > sum)
            {
                return Partition_Problem_IsSubset_Sum(arr, n - 1, sum);
            }

            return Partition_Problem_IsSubset_Sum(arr, n - 1, sum) || Partition_Problem_IsSubset_Sum(arr, n - 1, sum - arr[n - 1]);
        }

        static bool Partition_Problem_Solve(int[] arr, int n)
        {
            int sum = 0;
            for (int i = 0; i < n; i++)
            {
                sum += arr[i];
            }
            if (sum % 2 != 0)
            {
                return false;
            }
            return Partition_Problem_IsSubset_Sum(arr, n, sum / 2);
        }
        #endregion

        #region 算法2
        private static bool Partition_Problem_IsSubset_Sum(int[] arr, int n, int sum, int[,] dp)
        {
            if (sum == 0)
            {
                return true;
            }
            if (n == 0 && sum != 0)
            {
                return false;
            }
            if (dp[n, sum] != -1)
            {
                return true;
            }

            if (arr[n - 1] > sum)
            {
                return Partition_Problem_IsSubset_Sum(arr, n - 1, sum, dp);
            }

            dp[n, sum] = (Partition_Problem_IsSubset_Sum(arr, n - 1, sum, dp) || Partition_Problem_IsSubset_Sum(arr, n - 1, sum - arr[n - 1], dp)) ? 1 : -1;
            return dp[n, sum] > 0;
        }

        public static bool Partition_Problem_Solve_Second(int[] arr, int n)
        {
            int sum = 0;
            for (int i = 0; i < n; i++)
            {
                sum += arr[i];
            }
            if (sum % 2 != 0)
            {
                return false;
            }
            int[,] dp = new int[n + 1, sum + 1];

            return Partition_Problem_IsSubset_Sum(arr, n, sum / 2, dp);
        }
        #endregion

        #region 算法3
        public static bool Partition_Problem_Solve_Third(int[] arr, int n)
        {
            int sum = 0;
            for (int i = 0; i < n; i++)
            {
                sum += arr[i];
            }
            if (sum % 2 != 0)
            {
                return false;
            }

            bool[,] part = new bool[sum / 2 + 1, n + 1];
            for (int i = 0; i <= n; i++)
            {
                part[0, i] = true;
            }

            for (int i = 1; i <= sum / 2; i++)
            {
                part[i, 0] = false;
            }

            for (int i = 1; i <= sum / 2; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    part[i, j] = part[i, j - 1];
                    if (i >= arr[j - 1])
                    {
                        part[i, j] = part[i, j - 1] || part[i - arr[j - 1], j - 1];
                    }
                }
            }

            return part[sum / 2, n];
        }
        #endregion

        #region 算法4
        public static bool Partition_Problem_Solve_Fourth(int[] arr, int n)
        {
            int sum = 0;
            for (int i = 0; i < n; i++)
            {
                sum += arr[i];
            }
            if (sum % 2 != 0)
            {
                return false;
            }

            bool[] part = new bool[sum / 2 + 1];
            for (int i = 0; i <= sum / 2; i++)
            {
                part[i] = false;
            }

            for (int i = 0; i < n; i++)
            {
                for (int j = sum / 2; j >= arr[i]; j--)
                {
                    if (part[j - arr[i]] == true || j == arr[i])
                    {
                        part[j] = true;
                    }
                }
            }
            return part[sum / 2];
        }
        #endregion
    }
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python基础一

Python是一门简单的编程语言&#xff0c;适用于人工智能、web应用、爬虫程序、大数据等方面 一、Python语言特点 Python 是一种功能强大且流行的编程语言&#xff0c;具有许多特点&#xff0c;其中一些包括&#xff1a; 1. **易学易用** Python 的语法简洁清晰&#xff0c;类…

【go语言开发】gorm库连接和操作mysql,实现一个简单的用户注册和登录

本文主要介绍使用gorm库连接和操作mysql&#xff0c;首先安装gorm和mysql依赖库&#xff1b;然后初始化mysql&#xff0c;配置连接池等基本信息&#xff1b;然后建表、完成dao、controller开发&#xff1b;最后在swagger中测试 文章目录 前言安装依赖库数据库初始化账号注册和登…

springBoot整合Redis(三、整合Spring Cache)

缓存的框架太多了&#xff0c;各有各的优势&#xff0c;比如Redis、Memcached、Guava、Caffeine等等。 如果我们的程序想要使用缓存&#xff0c;就要与这些框架耦合。聪明的架构师已经在利用接口来降低耦合了&#xff0c;利用面向对象的抽象和多态的特性&#xff0c;做到业务代…

上市公司财务报表精讲系列一:黄山旅游

上市公司财务报表精讲系列一&#xff1a;黄山旅游 一、主营业务分行业、分产品、分地区情况二、董事会报告三、净利润现金流四、净资产收益率五、权益乘数和总资产周转率六、负债结构图七、行业分析八、案例总结九、2023年度业绩 一、主营业务分行业、分产品、分地区情况 二、董…

为国产信创服务器提供LDAP统一身份认证方案

金融信创作为 8 大行业信创之首&#xff0c;早已成为其他行业信创建设的参考。金融行业有着极为复杂的业务场景&#xff0c;对系统有着极高的稳定可靠需求&#xff0c;因此&#xff0c;在寻找微软 AD 国产化替代方案时&#xff0c;常会涉及到更深层次的场景。例如&#xff0c;最…

unity学习(45)——选择角色菜单——客户端处理服务器的数据

1.已知客户端ReceiveCallBack中已经收到来自服务器返回的数据包。 2.问题是客户端MessageManager中的Update并没有拆解该数据包 &#xff0c;因该是因为脚本没有挂载。 挂在SelectMenu场景中的Camera上即可。 挂载后成功达到目地 其中Update中的List是一个起到全局效果的static…

CVPR 2024 | Modular Blind Video Quality Assessment:模块化无参视频质量评估

无参视频质量评估 (Blind Video Quality Assessment&#xff0c;BVQA) 在评估和改善各种视频平台并服务用户的观看体验方面发挥着关键作用。当前基于深度学习的模型主要以下采样/局部块采样的形式分析视频内容&#xff0c;而忽视了实际空域分辨率和时域帧率对视频质量的影响&am…

学习 考证 帆软 FCP-FineBI V6.0 心得

学习背景&#xff1a; 自2024年1月起&#xff0c;大部分时间就在家里度过了&#xff0c;想着还是需要充实一下自己&#xff0c;我是一个充满热情的个体。由于之前公司也和帆软结缘&#xff0c;无论是 Fine-Report 和 Fine-BI 都有接触3年之久&#xff0c;但是主要做为管理者并…

MyBatis复杂映射开发之多对多查询

多对多查询的模型 用户表和角色表的关系为&#xff0c;一个用户有多个角色&#xff0c;一个角色被多个用户使用。 多对多查询的需求&#xff1a;查询所有用户的同时查询出该用户对应的所有角色。 startuml !theme plain top to bottom direction skinparam linetype ortho cl…

阿里云服务器使用教程_搭建网站教程_2024建站教程

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

XUbuntu22.04之显示实时网速(二百一十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

智能网联各地市政策盘点

本文旨在对2023年及2024年初各地市所出台的智能网联相关政策进行全面的梳理与总结。通过与此前发布的关于2023年和2024年初各部委、省、直辖市智能网联相关政策的盘点相互呼应&#xff0c;力求为读者呈现一个全面、系统的政策概览。 文 | 吴冬升 全文6000字&#xff0c;预计阅读…

html--3D爱心

文章目录 代码效果 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>爱心</title><style type"text/css">*{margin: 0px;border: 0px;}body{overflow: hidden;background-…

Docker-部署若依项目

文章目录 后端一、搭建局域网二、redis安装测试 三、MySQL安装四、后端项目放入位置及使用Dockerfile自定义镜像后端项目放入位置 前端配置检查各个端口是否启动nginx部署 首先得先把内部的文件给删除清空 docker images–查看有哪些文件 docker rmi -f ID–删除ID 后端 一、…

腾讯QQ推出AI聊天搭子;零一万物01AI宣布开源Yi-9B模型

&#x1f989; AI新闻 &#x1f680; 腾讯QQ推出AI聊天搭子&#xff0c;进军AI对话领域 摘要&#xff1a;腾讯QQ合作筑梦岛和混元助手&#xff0c;推出了AI对话功能“AI聊天搭子”&#xff0c;提供多种虚拟角色与用户实时互动&#xff0c;目前已开启测试。此外&#xff0c;抖…

STM32/GD32——I2C通信协议

芯片选型 Ciga Device — GD32F470系列 通讯规则 I2C协议&#xff08;或称IIC&#xff09;是由飞利浦&#xff08;现在的恩智浦半导体&#xff09;公司开发的一种通用的总线协议。它使用两根线&#xff08;时钟线和数据线&#xff09;来传输数据&#xff0c;支持多个设备共享…

智能设备 app 设计 —— 蓝蓝 UI 设计公司

今天给大家推荐是智能设备app设计&#xff0c;随着智能设备的逐渐普及随之操作app也越来越多&#xff0c;希望能给大家带来灵感 #日常灵感 #创意设计#UI提升#ui设计#app #设计案例分享|#设计 #产品设计#产品设计#设计灵感 #B端产品经理 #ui #产品 #美工 #交互 #产品经理 #开发 …

乐优商城(九)数据同步

1. 项目问题分析 现在项目中有三个独立的微服务&#xff1a; 商品微服务&#xff1a;原始数据保存在 MySQL 中&#xff0c;从 MySQL 中增删改查商品数据。搜索微服务&#xff1a;原始数据保存在 ES 的索引库中&#xff0c;从 ES 中查询商品数据。商品详情微服务&#xff1a;做…

怎么在图片上直接编辑文字?3个方法教你轻松编辑

怎么在图片上直接编辑文字&#xff1f;随着技术的飞速发展&#xff0c;图片编辑已经成为我们日常生活和工作中不可或缺的一部分。在图片上直接编辑文字&#xff0c;不仅能够添加说明和标注&#xff0c;提高信息的传达效率&#xff0c;还能够增强图片的美观和设计感&#xff0c;…

qt练习案例

记录一下qt练习案例&#xff0c;方便学习qt知识点 基本部件 案例1 需求&#xff0c;做一个标签&#xff0c;显示"你好"知识点&#xff0c;QLabel画面 4. 参考&#xff0c;Qt 之 QLabel 案例2 需求&#xff0c;做一个标签&#xff0c;显示图片 知识点&#xff0c;…