943,735 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 2382
  • C++ RSS
You are currently viewing page 2 of this multi-page discussion thread; Jump to the first page
Oct 10th, 2008
1

Re: number of ways to..ehh, i hate counting ways

Well, it's a good time to change notes:
C++ Syntax (Toggle Plain Text)
  1. /// Must be coin[0] < coin[1] < ... < coin[n-1]
  2. int NumberOfWays(int sum, const int coin[], int n) {
  3. if (0 >-- n)
  4. return 0;
  5. int high = coin[n];
  6. if (n == 0)
  7. return sum % high? 0: 1;
  8. int k = sum / high;
  9. int ways = 0;
  10. for (int i = 0; i <= k; ++i, sum -= high) {
  11. ways += NumberOfWays(sum, coin, n);
  12. }
  13. return ways;
  14. }
  15.  
  16. int main()
  17. {
  18. int coin[] = { 1, 2, 5, 25 };
  19. int n = sizeof coin / sizeof *coin;
  20. int ways, sum = 100;
  21. ways = NumberOfWays(sum,coin,n);
  22. std::cout << ways << std::endl;
  23. return 0;
  24. }
  25. // Output: 1042. Heaps of ways!..
Absolutely supersonic code ...
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

hmm, okay...that's fast... reps to you!
//edit
umm it's not that fast, i see now, mine is alot faster, you haven't optimized the recursion, so you're making calls that aren't needed... mine goes fast for 10000, your is slow. :O?
Last edited by gregorynoob; Oct 10th, 2008 at 10:02 am.
Reputation Points: 12
Solved Threads: 5
Junior Poster in Training
gregorynoob is offline Offline
86 posts
since Jun 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

OK, your code is faster.
No need in true recursion in this algorithm.
But I'm too lazy to do that ...
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

hehe, i'm lazy too, but i still wanna speed it up. found another way, without recursion, the idea is: no need to check for 1's, they always give 1, and 2's always give ( n/2 )+1...
still too slow
Last edited by gregorynoob; Oct 10th, 2008 at 11:17 am.
Reputation Points: 12
Solved Threads: 5
Junior Poster in Training
gregorynoob is offline Offline
86 posts
since Jun 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

It's a brutal force method to enumerate all deals.
Let this tin with silicic stuffing works...
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

do you think the same thing when discussing algorithms with O(2^n) time complexity? poor tin cans would struggle for centuries if n was...say 100.
Reputation Points: 12
Solved Threads: 5
Junior Poster in Training
gregorynoob is offline Offline
86 posts
since Jun 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

Of course, NP-complexity is a barrier. To be up against a blank wall?
But this alg is not k power n complexity (polynomial only).
Be careful with combinatory problems - that's all
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Oct 10th, 2008
0

Re: number of ways to..ehh, i hate counting ways

hmm, well now i've implemented it, but it's so damn slow... it should work fast for 100k atleast... here's my implementation:
c++ Syntax (Toggle Plain Text)
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define MOD 100000
  5. using namespace std;
  6.  
  7. const int coins[] = {1, 2, 5, 25};
  8.  
  9. int n, dp[100000][5];
  10.  
  11. int rec(int n, int m) {
  12. int ret = 0; if(dp[n][m]) return dp[n][m];
  13. if(m == 0 || n == 0) return (dp[n][m] = 1);
  14. if(n < coins[m]) return (rec(n, m-1));
  15. for(int i = 0; i*coins[m] <= n; ++i) {
  16. ret = ((ret%MOD) + (rec(n-i*coins[m], m-1)%MOD))%MOD;
  17. }
  18. return (dp[n][m] = ret);
  19. }
  20.  
  21. int main( void )
  22. {
  23. scanf("%d", &n);
  24.  
  25. memset(dp, 0, sizeof dp);
  26. printf("%d\n", rec(n, 3)%MOD);
  27.  
  28. return 0;
  29. }
i guess my implementation is stupid in some way... or can it run no faster?

Take all of the % MOD lines out of there. They give you bad results (i.e. there are 43 ways to make 515) and they slow the program down.

Second, it's not an issue here because the smallest "coin" is 1, but this line is a problem if the smallest "coin" is, say, 2:

C++ Syntax (Toggle Plain Text)
  1. if(m == 0 || n == 0) return (dp[n][m] = 1);

If coins[] = {2, 3, 5, 25} or something similar where the smallest element is not 1, ret (1, 0) would equal 0 (no way to to make 1 from {2, 3, 5, 25}). Thus if this algorithm is meant to cover all coins arrays, that line would need to change since dp[n][0] sometimes will equal 0 and sometimes will equal 1 for varying n values. So if you want to allow for that, you'd also need to set the array with memset to some negative number rather than 0 ahead of time if you are checking to see whether the array value has been filled and you allow the smallest coin to be greater than one.
Featured Poster
Reputation Points: 2614
Solved Threads: 687
Posting Expert
VernonDozier is offline Offline
5,372 posts
since Jan 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC