洛谷 P2725 [USACO3.1] 邮票 Stamps 题解
题目链接
思路分析
还是寻找代价和价值。由于是想让使用邮票数目不超过 \(k\),求连续区间,所以应为类似于可行性完全背包的题目,则代价就为邮票价值,对应价值即为邮票数目。定义 \(dp_j\) 表示邮票价值和为 \(j\) 时所需最少邮票数,状态转移方程与之前类似。
寻找答案时,从小到大枚举,遇到一个无法拼出(即 \(dp_j=+\infty\))的价值,直接输出其下标减 \(1\) 的值。注意枚举时要枚举到 \(k\times\max{a_i}\)。时间复杂度 \(O(nk\max{a_i})\)。
代码呈现
#include<bits/stdc++.h>
using namespace std;
const int N=55,M=2000010;
int k,n;
int a[N],dp[M];
int main(){
scanf("%d%d",&k,&n);
for (int i=1;i<=n;++i) scanf("%d",a+i);
int m=0;
for (int i=1;i<=n;++i) m=max(m,a[i]);
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for (int i=1;i<=n;++i){
for (int j=a[i];j<=m*k;++j) dp[j]=min(dp[j],dp[j-a[i]]+1);
}
for (int i=1;i<=m*k;++i){
if (dp[i]>k){ printf("%d",i-1);return 0; }
}
printf("%d",m*k);
return 0;
}

浙公网安备 33010602011771号