洛谷 P5020 【货币系统】
"简" "单" 的完全背包O_O
来一个开心的AC代码
#include<cstdio>
#include<cstring>
#define __________ 100005
#define ___________ "%d"
#define ____________ scanf
#define _____________ memset
#define ______________ int
#define _______________ for
#define ________________ while
#define _________________ inline
#define __________________ return
#define ___________________ main
#define ____________________ for
#define _____________________ if
#define ______________________ sizeof
#define _______________________ using
#define ________________________ namespace
#define _________________________ std
#define __________________________ printf
#define ______________________________________________________ "%d\n"
_______________________ ________________________ _________________________;
______________ _____,________[__________],___[__________],____=-1,_;
_________________ ______________ __(______________ ___________________________,______________ ____________________________){
__________________ ___________________________>____________________________?___________________________:____________________________;
}
______________ ___________________(){
____________(___________,&_);
________________(_--){
____=-1;
______________ ______=0;
_____________(___,0,______________________(___));
____________(___________,&_____);
___[0]=1;
____________________(______________ _______=1;_______<=_____;_______++){
____________(___________,&________[_______]);
____=__(____,________[_______]);
}
____________________(______________ _______=1;_______<=_____;_______++){
____________________(______________ _________=________[_______];_________<=____;_________++){
_____________________(___[_________-________[_______]])___[_________]++;
}
}
____________________(______________ _______=1;_______<=_____;_______++){
_____________________(___[________[_______]]>1){
______++;
}
}
__________________________(______________________________________________________,_____-______);
}
}
好吧他本来长这样
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[100005],dp[100005],maxx=-1;
inline int max(int x,int y){
return x>y?x:y;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
maxx=-1;
int ans=0;
memset(dp,0,sizeof(dp));
scanf("%d",&n);
dp[0]=1;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
maxx=max(maxx,a[i]);
}
for(int i=1;i<=n;i++){
for(int j=a[i];j<=maxx;j++){
if(dp[j-a[i]])dp[j]++;
}
}
for(int i=1;i<=n;i++){
if(dp[a[i]]>1){
ans++;
}
}
printf("%d\n",n-ans);
}
}
-
根据题意,如果某一种面额可以被其他钱币拼凑而成,那么它就可以舍去。
-
先dp出无穷多钱币可以拼凑出的钱币种类(小于最大面额即可)。如果一种钱数j可以被拼凑出,我们令dp[j]=1.
-
然后枚举提供的每种面额,如果dp值为1,那么ans(可以被舍去的面额的数量)++。
-
最后输出n-ans即可。
//然而考试的时候我完全背包打错了O_O惊吓,结果居然强势AC O_O