poj-1742 Coins(多重背包优化)
2016-04-11 13:04
405 查看
题目链接:http://poj.org/problem?id=1742
Coins
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
Sample Output
题意;n种硬币,目标金钱是m。每种硬币给你数目和价值,问在1~m之前最多能组成多少种钱。
思路:楼教主“男人八题”之一,此题看似简单,数据却十分变态。错的基本都是TLE。 二进制多重背包过不了,单调队列优化的多重背包也过不了,加了混合背包单调队列才卡过,只能说自己太弱了。对单调队列的理解不够深。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 100010
#define N 110
int dp[M];
int b[M];
int l,r;
int n,m;
int s
,flag[M];
int main()
{
int num,sum;
while(~scanf("%d %d",&n,&m)&&(n+m))
{
for(int i=1; i<=n; i++)
scanf("%d",&s[i]);
for(int i=1; i<=m; i++)
dp[i]=0;
dp[0]=1;
for(int i=1; i<=n; i++)
{
scanf("%d",&num);
int v=s[i];
if(num==1)
{
for(int j=m; j>=v; j--)
if(!dp[j]&&dp[j-v])
dp[j]=1;
}
else if(num*v>=m)
{
for(int j=v; j<=m; j++)
if(!dp[j]&&dp[j-v])
dp[j]=1;
}
else
{
for(int d=0; d<v; d++)
{
sum=0,l=1;r=0;
for(int j=d;j<=m;j+=v)
{
if(r-l+1>num)
sum-=b[l++];
b[++r]=dp[j];
sum+=dp[j];
if(!dp[j]&&sum)
dp[j]=1;
}
}
}
}
int t=0;
for(int i=1;i<=m;i++)
if(dp[i])
t++;
printf("%d\n",t);
}
return 0;
}
Coins
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 33242 | Accepted: 11283 |
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 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
Sample Output
8 4
题意;n种硬币,目标金钱是m。每种硬币给你数目和价值,问在1~m之前最多能组成多少种钱。
思路:楼教主“男人八题”之一,此题看似简单,数据却十分变态。错的基本都是TLE。 二进制多重背包过不了,单调队列优化的多重背包也过不了,加了混合背包单调队列才卡过,只能说自己太弱了。对单调队列的理解不够深。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 100010
#define N 110
int dp[M];
int b[M];
int l,r;
int n,m;
int s
,flag[M];
int main()
{
int num,sum;
while(~scanf("%d %d",&n,&m)&&(n+m))
{
for(int i=1; i<=n; i++)
scanf("%d",&s[i]);
for(int i=1; i<=m; i++)
dp[i]=0;
dp[0]=1;
for(int i=1; i<=n; i++)
{
scanf("%d",&num);
int v=s[i];
if(num==1)
{
for(int j=m; j>=v; j--)
if(!dp[j]&&dp[j-v])
dp[j]=1;
}
else if(num*v>=m)
{
for(int j=v; j<=m; j++)
if(!dp[j]&&dp[j-v])
dp[j]=1;
}
else
{
for(int d=0; d<v; d++)
{
sum=0,l=1;r=0;
for(int j=d;j<=m;j+=v)
{
if(r-l+1>num)
sum-=b[l++];
b[++r]=dp[j];
sum+=dp[j];
if(!dp[j]&&sum)
dp[j]=1;
}
}
}
}
int t=0;
for(int i=1;i<=m;i++)
if(dp[i])
t++;
printf("%d\n",t);
}
return 0;
}
相关文章推荐
- Android开发自定义ListView解决在NestedScrollView里不能用listview的问题(ScrollView嵌套ListView的问题)
- LinqToSqlite
- 跨浏览器兼容事件处理
- Unity IOS横版游戏 SplashImage 闪屏旋转 成竖屏的问题
- <meta> 标签
- USACO-Section 3.4 Electric Fence (模拟)
- 虚拟机挂在光盘
- linux 防火墙打开端口/屏蔽IP等
- 1、mac下安装MySQLWorkbench
- Notification的使用
- <!DOCTYPE> 标签
- html 实体编码转换成原字符
- 下一代机器学习-在浏览器中训练深度学习模型Next Generation Machine Learning - Training Deep Learning Models in a Browser
- 台州3128 简单版贪吃蛇 bfs保存路径 解题报告
- 【项目积累】对JSON数据的处理
- Tomcat清除缓存
- Jersey开发Restful的文件上传接口如何传递数组参数
- LeetCode 之 Search a 2D Matrix
- 量化生产力Quantifying Productivity
- leetcode 108. Convert Sorted Array to Binary Search Tree