【usaco】Bessie's Secret Pasture 贝茜的秘密草坪

Bessie's Secret Pasture 贝茜的秘密草坪

这道题dp的转移的方式很妙,值得一记。

说实话,拿到这道题,我先想到的是一个5维的转移方程,不详细说,大概可以理解为我记录了各个重复物品的情况吧,毕竟最终方案是要考虑顺序的;我的目的是先跑多重背包,然后在答案处最后求组合数,然而实现太麻烦。

看了题解,我才感慨。

 

让我们直接看看状态枚举吧:

这是我们熟知的 01背包 的写法:先枚举物品,再枚举体积

而在此基础上的 多重背包 的写法:先枚举物品,接着是枚举放置物品个数,最后枚举体积

另外还有 记录已放物品数量的01背包 的写法:先枚举物品,接着是已放置物品个数,最后枚举体积 (最后两个好像可以调换)

而这道题则做出了美妙的变化:先枚举体积,再已放置物品个数,再枚举体积。 实际上这种做法放宽了转移,有意维护了选取物品顺序的随机

 

#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF (0x3f3f3f3f)
#define F(x, y, z) for(int x=y; x<=z; x++)
#define D(x, y, z) for(int x=z; x>=y; x--)
#define Mem(x, y) memset(x, (y), sizeof(x))
using namespace std;
#define N (10000)
#define L (500)
int n, n2, dp[N+L][5];
int main () 
{
    cin >> n; n2=sqrt(n);
    dp[0][0]=1; F(i, 1, n) F(j, 1, 4) for(int k=0; k*k<=i; k++) dp[i][j]+=dp[i-k*k][j-1];
    cout << dp[n][1]+dp[n][2]+dp[n][3]+dp[n][4];
    return 0; 
}

 

  

转载于:https://www.cnblogs.com/ToMySoul/p/7701374.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值