【羊圈——状压 + DP / 记忆化搜索DP】

题目

一般DP代码(注意,这里只能向外推(起始状态是f(1,0),不能向内推(不然会导致之前的羊圈被割裂))

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 210;
const int MAX_M = 16;

int n, m;
double p[MAX_N];
int l[MAX_M];
double dp[MAX_N][1 << MAX_M];

int main() {
    cin >> m >> n;
    for (int i = 1; i <= m; i++) cin >> l[i];
    for (int i = 1; i <= n; i++) cin >> p[i];

    int mask = 1 << m;
    for (int i = 0; i <= n + 1; i++) {
        for (int j = 0; j < mask; j++) {
            dp[i][j] = 1e18;
        }
    }
    dp[1][0] = 0;

    for (int u = 1; u <= n; u++) {
        for (int s = 0; s < mask; s++) {
            if (dp[u][s] == 1e18) continue;

            // 不覆盖当前羊u
            if (u + 1 <= n + 1) {
                dp[u + 1][s] = min(dp[u + 1][s], dp[u][s] + p[u]);
            }

            // 尝试用未使用的羊圈i覆盖
            for (int i = 1; i <= m; i++) {
                if (!(s & (1 << (i - 1))) && u + l[i] - 1 <= n) {
                    int new_s = s | (1 << (i - 1));
                    dp[u + l[i]][new_s] = min(dp[u + l[i]][new_s], dp[u][s]);
                }
            }
        }
    }

    double ans = 1e18;
    for (int s = 0; s < mask; s++) {
        ans = min(ans, dp[n + 1][s]);
    }
    printf("%.2lf\n", ans);

    return 0;
}

记忆化搜索DP代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using db = double;

int n, m;
db p[210];
int w[20];
db dp[210][(1 << 15) + 10];

db f(int u, int s)
{
	if(u >= n+1) return 0;
	if(dp[u][s] != -1) return dp[u][s];
	
	db ret = 1e18;
	
	//不用,状态不变,但是值要增加(这里的值指的是逃跑期望)
	ret = p[u] + f(u+1, s);
	
	//用
	for(int i = 1; i <= m; i++)
	{
		if(!(s & (1 << (i-1))) && u + w[i] - 1 <= n)
		{
			ret = min(ret, f(u+w[i], s | (1 << (i-1))));
		}
	}
	
	return dp[u][s] = ret;
}
int main()
{
	cin >> m >> n;
	for(int i = 1; i <= m; i++)
		cin >> w[i];
	for(int i = 1; i <= n; i++)
		cin >> p[i];
	
	for(int i = 1; i <= n; i++)	
		for(int j = 0; j < 1 << m; j++)
			dp[i][j] = -1;
			
	printf("%.2lf", f(1, 0));
}

感想

另外勘误

这题很多解法都是没看到"最多"吗

为什么要加这个限制?

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using db = double;

int n, m;
db p[210];
int w[20];
db dp[210][(1 << 15) + 10];

db f(int u, int s)
{
	if(u >= n+1) return 0;
	if(dp[u][s] != -1) return dp[u][s];
	
	db ret = 1e18;
	
	//不用,状态不变,但是值要增加(这里的值指的是逃跑期望)
	ret = p[u] + f(u+1, s);
	
	//用
	for(int i = 1; i <= m; i++)
	{
		if(!(s & (1 << (i-1))))
		{
			ret = min(ret, f(u+w[i], s | (1 << (i-1))));
		}
	}
	
	return dp[u][s] = ret;
}
int main()
{
	cin >> m >> n;
	for(int i = 1; i <= m; i++)
		cin >> w[i];
	for(int i = 1; i <= n; i++)
		cin >> p[i];
	
	for(int i = 1; i <= n; i++)	
		for(int j = 0; j < 1 << m; j++)
			dp[i][j] = -1;
			
	printf("%.2lf", f(1, 0));
}
相关推荐
森焱森18 分钟前
APM与ChibiOS系统
c语言·单片机·算法·架构·无人机
★Orange★29 分钟前
Linux Kernel kfifo 实现和巧妙设计
linux·运维·算法
尘世闲鱼32 分钟前
解数独(C++版本)
开发语言·c++·算法·解数独
qqxhb37 分钟前
零基础数据结构与算法——第四章:基础算法-排序(中)
数据结构·算法·排序算法·归并·快排·堆排
Y1nhl2 小时前
力扣_链表_python版本
开发语言·python·算法·leetcode·链表·职场和发展
qq_401700412 小时前
C语言中位运算以及获取低8位和高8位、高低位合并
c语言·开发语言·算法
CoovallyAIHub2 小时前
YOLO模型优化全攻略:从“准”到“快”,全靠这些招!
深度学习·算法·计算机视觉
闻缺陷则喜何志丹2 小时前
【BFS】 P10864 [HBCPC2024] Genshin Impact Startup Forbidden II|普及+
c++·算法·宽度优先·洛谷
MicroTech20253 小时前
微算法科技(NASDAQ: MLGO)探索Grover量子搜索算法,利用量子叠加和干涉原理,实现在无序数据库中快速定位目标信息的效果。
数据库·科技·算法
今天背单词了吗9803 小时前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题