#include <stdio.h> int main() { int postage[15]={8,8,8,8,8,10,10,10,10,18,18,18,18,18,18}; int dp[189]={1}; //组合出来的邮资小于等于188(角) int i,j; for(i=0;i<15;i++) { for(j=188;j>=postage[i];j--) { if(dp[j-postage[i]]!=0)dp[j]=1; } } j=0; for(i=8;i<=188;i++)if(dp[i]!=0)j++; //组合不出来8角以下的 printf("%d",j); }
#include<stdio.h> int main() { int i,j,k,num=0;//张数 float sum[1000]; for(i=0;i<=5;i++) for(j=0;j<=4;j++) for(k=0;k<=6;k++) { if(i==0&&j==0&&k==0) continue;//0张邮票不参与 sum[num++]=0.8*i+1*j+1.8*k; } for(i=0;i<num;i++)//去重 { for(j=i+1;j<num;j++) if(sum[i]==sum[j]) { sum[j]=sum[num-1];//把最后一个数拿过来 num--;j--;//个数减一,在从当前位置开始 } } printf("%d",num); }
#include<iostream> #include<set> using namespace std; int main() { set<int> st; for(int i=0;i<=5;i++) { for(int j=0;j<=4;j++) { for(int k=0;k<=6;k++) { if(i==0&&j==0&&k==0) continue; else st.insert(i*8 + j*10 + k*18); } } } cout<<st.size()<<endl; return 0; }
//用set最方便,直接去掉重复的,也不用开辟很大的数组,空间上效率高得多。
import java.util.HashSet; import java.util.Set; public class Main { public static void main(String[] args) { int x=8; int y=10; int z=18; int sum=0; HashSet set=new HashSet(); for(int i=0;i<=5;i++){ for(int j=0;j<=4;j++){ for(int k=0;k<=6;k++){ sum=i*x+j*y+k*z; set.add(sum); } } } System.out.println(set.size()-1); } }
#include <cstdio> #include <iostream> #include <algorithm> #include <map> #include <cmath> #include <cctype> using namespace std; int num[1000]; int main(){ int a,b,c; int j = 0; for(int a = 0;a <= 5;a++) for(int b = 0;b <= 4;b++) for(int c = 0;c <= 6;c++){ num[j++] = a*8+b*10+c*18; } sort(num,num+j); int sum = 0; for(int i = 1;i < j;i++){ if(num[i]!=num[i-1]) sum++; } cout<<sum; }
解题思路: 1.根据题意,邮票的组合情况有三种,分别是只有一种邮票,只有两种邮票和三种邮票都有的情况。 求解方法就是有几种邮票就有几层循环。 2.利用集合的性质,元素是不会有重复的,所以集合中元素的个数就是答案。 3.看了一下前面大佬的答案,忽然才想到,只要求算出个数的话,可以把小数化为整数,都扩大十倍 是不会有影响的,不同的数也不会变成相同,用小数算的话其实是有风险的,double和float要小 心谨慎地使用,如果元素精度高,在set中会严格按照你开的set的精度来排序,但是如果你输出 的时候精度没有达到那么高就会被四舍五入,那么你会发现set中居然存在两个相同的元素,其实他 们是不同的,后面的小数不同。 这是本人第一次写题解,如果有什么不正确的地方,欢迎大家批评指正。
#include <stdio.h> int main(){ int th[200]={0}; for(int i=0;i<=5;i++){ for(int j=0;j<=4;j++){ for(int k=0; k<=6;k++){ th[4*i+5*j+9*k]=1; } } } int num=0; for(int i=0;i<200;i++){ if(th[i]==1){ num++; } } printf("%d",num-1); }思路: 把每种方案映射到数组中,重复的依旧记作1,统计方案的个数。
#include<iostream> using namespace std; int dp[189]; void Initial() { for (int i = 0; i < 189; i++) //初始dp数组 { if (i == 0) dp[i] = 1; else dp[i] = 0; } } int main() { Initial(); int a[] = {0,8,8,8,8,8,10,10,10,10,18,18,18,18,18,18}; for(int i=1;i<16;i++) //0-1背包变形 for (int j = 188; j >= a[i]; j--) { dp[j] = dp[j] + dp[j - a[i]]; } int count = 0; for (int i = 1; i < 189; i++) //统计1-188能装满的方案数 if (dp[i] != 0) count++; cout << count << endl; }
#include <iostream> using namespace std; #define max 8 * 5 + 10 * 4 + 18 * 6 //最大邮资数(单位:角) int main() { int count[max + 1] = {0}; //统计每种邮资可能情况数 for (int i = 0; i <= 5; i++) for (int j = 0; j <= 4; j++) for (int k = 0; k <= 6; k++) { int value = 8 * i + 10 * j + 18 * k; //邮资值(单位:角) if (value != 0)count[value]++; } int num = 0; //邮资种数 for (int i = 1; i <= max; i++) if (count[i] > 0) num++; //邮资值存在,邮资种数增1 cout << num; }
#include<iostream> #include<set> #define v1 8 #define v2 10 #define v3 18 using namespace std; int main() { set<int> value; int len=0; for(int i=0;i<=6;i++)//1.8元 { for(int j=0;j<=4;j++)//1元 { for(int k=0;k<=5;k++)//0.8元 { int total=i*v3+j*v2+k*v1; value.insert(total); } } } cout<<value.size()-1<<endl; }