HAOI coin shopping, haoi coin shopping
Question description:
There are currently four types of coins with different nominal values: ci (I = 1, 2, 4 ). Someone goes to the store to buy things, and goes to tot. Each time they bring di ci coins, they buy goods worth si. How many payment methods are there each time.
Input:
The first row contains five numbers, namely c1, c2, c3, c4, and tot. Next there are five numbers in each row, the fifth number in the I + 1 row is the number of four coins taken by the I shopping and the value of the purchased goods (d1, d2, d3, d4, s ). Each row is separated by a space.
Output:
The number of methods for each payment.
Input example:
1 2 5 10 2
3 2 3 1 10
1000 2 2 900
Output example:
4
27
Data range:
0 <di, s <= 1000, 0 <tot <=.
This question is actually a dp + refresh principle (I don't know what is the refresh principle, I am going to go online to Baidu )......
First, we first perform initial operations on the dp array. We define that dp [I] is the number of I-yuan schemes to be collected with coins without considering whether coins exceed the limit. In this way, we can obtain the state equation: dp [j] + = dp [j-c [I] (0 <= j <= 100000,1 <= I <= 4) discovered by data. Note: dp [0] = 1
Then we can proceed with the rejection principle. For each coin, there are two situations: Super and no super, so we only need to count 2 ^ 4 = 16 times in the end. When recording the status, we can use a decimal number to record the status. However, during the operation, we actually perform the binary operation. For example, if I use 5 to record a state, the binary value of 5 is 0101, which means that the first and third types of coins exceed the limit.
So how should we express that the use of coins exceeds the limit? For example, if the I-th coin contains d [I] coins, if we use d [I] + 1 coin, it means we have used more than the limit, and other coins can be used at will, therefore, dp [s-c [I] * (d [I] + 1)] may be used in this case, if s-c [I] * (d [I] + 1) <0, the number of solutions is 0. The rest is similar.
This question is about long, but not ...... I am so dead ......
AC code:
#include<iostream>#include<memory.h>#include<stdio.h>#include<cstdio>#include<cctype>using namespace std;//--------------------------void read(long long &x){ x=0;char ch=getchar();long long f=1; for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0'; x*=f;}//---------------------------long long c[5],d[5],s,tot,ans,cnt,sum,cur;long long dp[100000+10];bool flag=0;int main(){ for(int i=1;i<=4;i++){ read(c[i]); } read(tot); dp[0]=1; for(int i=1;i<=4;i++){ for(int j=c[i];j<=100000;j++)dp[j]+=dp[j-c[i]]; } while(tot--){ for(int i=1;i<=4;i++)read(d[i]); read(s); ans=0; for(int i=0;i<16;i++){ cnt=0;sum=0;cur=0; int t=i; while(t>0){ cur++; if(t&1)sum+=(d[cur]+1)*c[cur],cnt++; t>>=1; } if(s<sum)continue; if(cnt&1)ans-=dp[s-sum]; else ans+=dp[s-sum]; } printf("%lld\n",ans); }}