#include <stdio.h> #define DEBUG 1 #define TESTCASES 9 //ways[coinageValueIndex][constructedMoney]表示考虑前coinageValueIndex种钱币凑成constructedMoney的数量的钱时的方案数,第coinageValueIndex种钱币可以选或者不选 //数组很大要声明为全局变量,如果声明为局部变量栈会溢出 long long ways[26][10001]; int main(){ #if DEBUG int testCase; for (testCase = 1; testCase <= TESTCASES; testCase++){ char inputFileName[20] = "inputX.txt"; inputFileName[5] = '1' + (testCase - 1); freopen(inputFileName, "r", stdin); printf("\n#%d\n", testCase); #endif int typesOfCoins, moneyToConstruct; scanf("%d%d", &typesOfCoins, &moneyToConstruct); int coinageValueArray[26]; int coinageValueIndex; for (coinageValueIndex = 1; coinageValueIndex <= typesOfCoins; coinageValueIndex++) scanf("%d", &coinageValueArray[coinageValueIndex]); int constructedMoney; for (coinageValueIndex = 0; coinageValueIndex <= typesOfCoins; coinageValueIndex++) for (constructedMoney = 0; constructedMoney <= moneyToConstruct; constructedMoney++) if (constructedMoney == 0) ways[coinageValueIndex][constructedMoney] = 1; else ways[coinageValueIndex][constructedMoney] = 0; for (coinageValueIndex = 1; coinageValueIndex <= typesOfCoins; coinageValueIndex++) for (constructedMoney = 1; constructedMoney <= moneyToConstruct; constructedMoney++) if (constructedMoney < coinageValueArray[coinageValueIndex] ) ways[coinageValueIndex][constructedMoney] = ways[coinageValueIndex - 1][constructedMoney]; else //ways[coinageValueIndex][constructedMoney - coinageValueArray[coinageValueIndex]]可以通过递增遍历constructedMoney的方式来优化ways空间成关于constructedMoney的一维数组,又因为当constructedMoney < coinageValueArray[coinageValueIndex]时,ways[coinageValueIndex][constructedMoney] = ways[coinageValueIndex - 1][constructedMoney]所以递增遍历constructedMoney的时候可以直接从constructedMoney = coinageValueArray[coinageValueIndex]开始遍历 ways[coinageValueIndex][constructedMoney] = ways[coinageValueIndex - 1][constructedMoney] + ways[coinageValueIndex][constructedMoney - coinageValueArray[coinageValueIndex]]; printf("%lld\n", ways[typesOfCoins][moneyToConstruct]); #if DEBUG } #endif return 0; }