poj1742(dp优化递推关系式)

来源:互联网 发布:java rest接口 编辑:程序博客网 时间:2024/04/28 18:13

Coins 

Time Limit: 3000MS

Memory Limit: 30000K

[显示标签]

Description

People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.

Input

The input contains several test cases. The first line of each test case contains two integers n(1<=n<=100),m(m<=100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000). The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

3 101 2 4 2 1 12 51 4 2 10 0

Sample Output

84

/*背包问题,此题中由于朴素算法需要三重循环,所以需要变换思路改成二重循环在朴素算法中,第三重循环来自于每种钱的数量,而既然每次1到m都需要遍历,每次都从一个可行的点遍历钱的数量的次数,这些遍历出来的点其实在第二重下面的遍历中一定会遇到,所以这个就是优化方向如果在二重循环中遍历的点能知道需要多少个这种钱的数量就好了,所以用一个cnt数组存下在使用1-i面额的钱时,达到j总额需要使用i面额的钱多少 */#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define maxn 105#define maxm 100010int n,m;bool dp[maxm];int cnt[maxm];pair<int,int> p[maxn];void solve(){memset(dp,0,sizeof(dp));//memset(cnt,0,sizeof(cnt));dp[0]=1;           //初始化,代表前面i-1的钱全不使用 int ans=0;for(int i=0;i<n;i++){memset(cnt,0,sizeof(cnt));    //对于每种面额的都要初始化 for(int j=p[i].first;j<=m;j++){//由于是自少向多,如果j可以的话,j-p[i].first必定是可以达到,并且要保证钱的用量不超 if(!dp[j]&&dp[j-p[i].first]&&cnt[j-p[i].first]<p[i].second){dp[j]=1;cnt[j]=cnt[j-p[i].first]+1;ans++;}}}cout<<ans<<endl;}int main(){while(cin>>n>>m&&(n||m)){for(int i=0;i<n;i++)cin>>p[i].first;for(int i=0;i<n;i++)cin>>p[i].second;solve();}}




原创粉丝点击