[usaco]5.3.2 Milk Measuring 动态规划

 
Milk Measuring
Hal Burch
Farmer John must measure Q (1 <= Q <= 20,000) quarts of his finest milk and deliver it in one big bottle to a customer. He fills that bottle with exactly the number of quarts that the customer orders.

Farmer John has always been frugal. He is at the cow hardware store where he must purchase a set of pails with which to measure out Q quarts of milk from his giant milk tank. Since the pails each cost the same amount, your task is to figure out a minimal
set of pails Farmer John can purchase in order to fill a bottle with exactly Q quarts of milk. Additionally, since Farmer John has to carry the pails home, given two minimal sets of pails he should choose the "smaller" one as follows: Sort the sets in ascending
order. Compare the first pail in each set and choose the set with the smallest pail. If the first pails match, compare the second pails and choose from among those, else continue until the two sets differ. Thus the set {3, 5, 7, 100} should be chosen over
{3, 6, 7, 8}.

To measure out milk, FJ may completely fill a pail from the tank and pour it into the bottle. He can never remove milk from the bottle or pour milk anywhere except into the bottle. With a one-quart pail, FJ would need only one pail to create any number of
quarts in a bottle. Other pail combinations are not so convenient.

Determine the optimally small number of pails to purchase, given the guarantee that at least one solution is possible for all contest input data.

PROGRAM NAME: milk4
INPUT FORMAT
Line 1: The single integer Q 
Line 2: A single integer P (1 <= P <= 100) which is the number of pails in the store 

Lines 3..P+2: Each line contains a single integer pail_value (1 <= pail_value <= 10000), the number of quarts a pail holds 

SAMPLE INPUT (file milk4.in)
16
3
3
5
7

OUTPUT FORMAT
The output is a single line of space separated integers that contains:

the minimum number of pails required to measure out the desired number of quarts, followed by:

a sorted list (from smallest to largest) of the capacity of each of the required pails

SAMPLE OUTPUT (file milk4.out)
2 3 5

 

--------------------------------------------------------------------------------
典型的动态规划,但是这里有两个条件:桶最少;相同数目的桶,取比较小的那些。
不过,当这两个条件相互冲突时,应该如何取舍?
使用动态规划的基本思路是:
如果能够满足q量的牛奶,那么这q+任一个桶的量所得的数目也一定能够满足。

   Test 1: TEST OK [0.000 secs, 5080 KB]
   Test 2: TEST OK [0.000 secs, 5080 KB]
   Test 3: TEST OK [0.000 secs, 5080 KB]
   Test 4: TEST OK [0.000 secs, 5080 KB]
   Test 5: TEST OK [0.000 secs, 5080 KB]
   Test 6: TEST OK [0.000 secs, 5080 KB]
   Test 7: TEST OK [0.027 secs, 5080 KB]
   Test 8: TEST OK [0.135 secs, 5080 KB]
   Test 9: TEST OK [0.054 secs, 5080 KB]
   Test 10: TEST OK [0.135 secs, 5080 KB]
我在网上找这个的测试用例的时候,没法先哪个人上传过的,因此特地把测试用例作为附件上传。

/*
ID:yunleis3
PROG:milk4
LANG:C++
*/

#include <fstream>
#include<iostream>

using namespace std;
const int maxq=20001;
const int maxp=101;
bool metri[maxq][maxp];
int pailnum[maxq];
int q,p;
//#define  DEBUG
int pail[maxp];

void quicksort(int * a,int p,int r);
int middleq;
int main()
{
	ifstream fin("milk4.in");
	fin>>q>>p;
	for(int i=0;i<p;++i){
		fin>>pail[i];
		metri[pail[i]][i]=true;
		pailnum[pail[i]]=1;
	}
	//quicksort(pail,0,p-1);
	 solve1();

	int *result1=new int[pailnum[q]];
	int ptr1=0;
	for(int i=0;i<p;++i){
		if(metri[q][i])
			result1[ptr1++]=pail[i];
	}
	quicksort(result1,0,ptr1-1);
	for(int i=0;i<q;++i){
		for(int j=0;j<p;++j)
			metri[i][j]=false;
		pailnum[i]=0;
	}
	for(int i=0;i<p;++i){
		metri[pail[i]][i]=true;
		pailnum[pail[i]]=1;
	}
	 nochange=true;
	for(int i=1;i<=q&&nochange;++i){
		nochange=false;
		for(int j=0;j<p;++j){
			if(i+pail[j]>q)
				continue;
			nochange=true;
			int num=metri[i][j]?0:1;
			bool flag=false;
			if(pailnum[i]==0)
				flag=false;
		//	else if(pailnum[i+pail[j]]==0||(num+pailnum[i])<pailnum[i+pail[j]]){
			//	flag=true;
			//}
			else {
				bool metritmp=metri[i][j];
				metri[i][j]=true;
				for(int ss=0;ss<=p;++ss){
					if(metri[i][ss]&&!metri[i+pail[j]][ss]){
						flag=true;
						break;
					}
					else if(!metri[i][ss]&&metri[i+pail[j]][ss])
						break;
				}
				metri[i][j]=metritmp;
			}
			if(flag){
				for(int ss=0;ss<p;++ss){
					metri[i+pail[j]][ss]=metri[i][ss];
				}
				metri[i+pail[j]][j]=true;
				pailnum[i+pail[j]]=(num+pailnum[i]);

			}
		}
	}
	ofstream fout("milk4.out");

	int *result=new int[pailnum[q]];
	int ptr=0;
	for(int i=0;i<p;++i){
		if(metri[q][i])
			result[ptr++]=pail[i];//fout<<" "<<pail[i];
	}
	p=ptr;
	for(int i=0;i<q;++i){
		for(int j=0;j<p;++j)
			metri[i][j]=false;
		pailnum[i]=0;
	}
	for(int i=0;i<p;++i){
		pail[i]=result[i];
		metri[pail[i]][i]=true;
		pailnum[pail[i]]=1;
	}
	solve1();

	ptr=0;
	for(int i=0;i<p;++i){
		if(metri[q][i])
			result[ptr++]=pail[i];//fout<<" "<<pail[i];
	}
	if(ptr1<ptr)
	{
		int * resulttmp=result1;
		result1=result;
		result=resulttmp;
		ptr=ptr1;
	}
	else if(ptr1==ptr){

	}
 	fout<<ptr;
	quicksort(result,0,ptr-1);
	for(int i=0;i<ptr;++i)
		fout<<" "<<result[i];
	fout<<endl;
	delete [] result;
	delete [] result1;
	//system("pause");
}
 void solve1()
 {
	bool  nochange=true;
	 for(int i=1;i<=q&&nochange;++i){
		 nochange=false;
		 for(int j=0;j<p;++j){
			 if(i+pail[j]>q)
				 continue;
			 nochange=true;
			 int num=metri[i][j]?0:1;
			 bool flag=false;
			 if(pailnum[i]==0)
				 flag=false;
			 else if(pailnum[i+pail[j]]==0||(num+pailnum[i])<pailnum[i+pail[j]]){
				 flag=true;
			 }
			 else if((num+pailnum[i])==pailnum[i+pail[j]]){
				 bool metritmp=metri[i][j];
				 metri[i][j]=true;
				 for(int ss=0;ss<=p;++ss){
					 if(metri[i][ss]&&!metri[i+pail[j]][ss]){
						 flag=true;
						 break;
					 }
					 else if(!metri[i][ss]&&metri[i+pail[j]][ss])
						 break;
				 }
				 metri[i][j]=metritmp;
			 }
			 if(flag){
				 for(int ss=0;ss<p;++ss){
					 metri[i+pail[j]][ss]=metri[i][ss];
				 }
				 metri[i+pail[j]][j]=true;
				 pailnum[i+pail[j]]=(num+pailnum[i]);

			 }
		 }
	 }

 }
void swap(int * a,int * b){
	int t=*a;
	*a=*b;
	*b=t;
}
int partion(int * a,int p,int r){
	int x=a[r];
	int i=p-1;
	for(int j=p;j<r;++j){
		if(a[j]<x){
			i++;
			swap(a+i,a+j);
		}
	}
	i++;
	swap(a+r,a+i);
	return i;
}
void quicksort(int * a,int p,int r){
	if(p<r){
		int q=partion(a,p,r);
		quicksort(a,p,q-1);
		quicksort(a,q+1,r);
	}
}

--------------------------------------

Here are the test data inputs:

------- test 1 ----
16
3
3
5
7
------- test 2 ----
20
3
1
2
4
------- test 3 ----
59
3
7
11
13
------- test 4 ----
8722
2
89
97
------- test 5 ----
323
5
97
101
103
107
119
------- test 6 ----
20000
3
233
151
413
------- test 7 ----
5334
100
1009
1013
1019
1021
1031
1033
1039
1049
1051
1061
1063
1069
1087
1091
1093
1097
1103
1109
1117
1123
1129
1151
1153
1163
1171
1181
1187
1193
1201
1213
1217
1223
1229
1231
1237
1249
1259
1277
1279
1283
1289
1291
1297
1301
1303
1307
1319
1321
1327
1361
1367
1373
1381
1399
1409
1423
1427
1429
1433
1439
1447
1451
1453
1459
1471
1481
1483
1487
1489
1493
1499
1511
1523
1531
1543
1549
1553
1559
1567
1571
1579
1583
1597
1601
1607
1609
1613
1619
1621
1627
1637
1657
1663
1667
1669
1693
1697
1699
1709
1721
------- test 8 ----
15383
100
997
998
1000
1003
1007
1012
1018
1025
1033
1042
1052
1063
1075
1088
1102
1117
1133
1150
1168
1187
1207
1228
1250
1273
1297
1322
1348
1375
1403
1432
1462
1493
1525
1558
1592
1627
1663
1700
1738
1777
1817
1858
1900
1943
1987
2032
2078
2125
2173
2222
2272
2323
2375
2428
2482
2537
2593
2650
2708
2767
2827
2888
2950
3013
3077
3142
3208
3275
3343
3412
3482
3553
3625
3698
3772
3847
3923
4000
4078
4157
4237
4318
4400
4483
4567
4652
4738
4825
4913
5002
5092
5183
5275
5368
5462
5557
5653
5750
5848
5947
------- test 9 ----
19829
20
708
727
764
825
916
1043
1212
1429
1700
2031
2428
2897
3444
4075
4796
5613
6532
7559
8700
9961
------- test 10 ----
16737
94
904
909
916
925
936
949
964
981
1000
1021
1044
1069
1096
1125
1156
1189
1224
1261
1300
1341
1384
1429
1476
1525
1576
1629
1684
1741
1800
1861
1924
1989
2056
2125
2196
2269
2344
2421
2500
2581
2664
2749
2836
2925
3016
3109
3204
3301
3400
3501
3604
3709
3816
3925
4036
4149
4264
4381
4500
4621
4744
4869
4996
5125
5256
5389
5524
5661
5800
5941
6084
6229
6376
6525
6676
6829
6984
7141
7300
7461
7624
7789
7956
8125
8296
8469
8644
8821
9000
9181
9364
9549
9736
9925

 

 

 

时间: 2024-11-03 19:07:07

[usaco]5.3.2 Milk Measuring 动态规划的相关文章

[usaco]3.4.4 变形的动态规划问题Electric Fence

Electric Fence Don Piele In this problem, `lattice points' in the plane are points with integer coordinates. In order to contain his cows, Farmer John constructs a triangular electric fence by stringing a "hot" wire from the origin (0,0) to a la

经典动态规划基础题-三角形最大和问题

三角形最大和问题 Time Limit:1000MS Memory Limit:65536K Total Submit:79 Accepted:22 Description 现在经常有一些数学问题困扰着小明.有如下一个三角形, 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 小明想求出从顶至底的某处的一条路径,使该路径所经过的数字的总和最大.现在想请你编一个程序实现这个问题. 说明: (1)每一步可沿左斜线向下或右斜线向下: (2)1<三角形行数≤100; (3)三角形中的数字为0,

代码-动态规划问题,求答案

问题描述 动态规划问题,求答案 Description 一个国家有n个城市(n不超过1000),一名旅行家住在最西边的城市里,他希望不重不漏地将每个城市浏览一遍.他的路线将是先向东经过一些城市到达最东边的城市,再向西依次经过剩余城市回到原来所在城市,任意两个城市均可直接相互到达.现给出所有城市的坐标,两个城市间的距离即为坐标两点间的直线距离.求旅行家所需走过的最短距离.Input第一行为整数n,是城市个数.接下来n行,每行两个整数xy,表示某个城市的坐标.保证坐标在32位整数范围内.保证最西和最

交互设计工作分享:milk香港版交互设计分享

文章描述:milk香港版--交互设计漫谈. 当产品相对稳定与可控,小神有愿望快速记录这个项目. 内容涉及小神参与产品设计与执行的过程,由交互/视觉设计层面的需求分析.功能设计与设计执行组成. 与其带入一些工作中的设计技巧,小神更愿意分享其中的设计思想与理念憧憬. 设计之所以不同于美化,是因为前者被赋予了驱动的灵魂. 背景 milk香港版,内部命名"milk mobile".是香港潮流杂志<milk>在移动新领域的合作尝试.目标设备为主流的中高端便携移动设备,iPhone/i

博弈树,动态规划(计算好的子问题存储起来,以后直接取用)

public class GameTree { /** * 判断剩余球数,谁能取到最后谁赢, * ,一人取一次,默认我方先取,,能否必胜,能就返回true,否则false * @param x剩余球数 * @return */ static boolean f(int x){ int[] op={1,3,7,8};//每次取球只能有四种情况 for(int i=0;i<op.length;i++){ if (x>=op[i]) { if(f(x-op[i])==false)return tru

从装配线到DNA比对——神器动态规划

对于一个问题,我们如果可以枚举所有的解,那么这个解空间我们是知道的.那么如何在解空间里面找到最优解呢?这时有一个非常好的方法,从底向上地构造整个解,而每一步都是从地层寻求最优解,这样就能保证在最终得到的一定是最优解.这就是最优子结构,有这种结构的问题,通常都可以用动态规划的办法来寻求最优解.而且它是从小规模(子问题)到大规模问题的构造,而常常这样的解法能够用一张表直观地表现出来.表中的元素是一个表达式的某个特定值,这个表达式表现的是问题和子问题的关系,也就是如何在子问题中的解中寻找最优的关系,这

动态规划(DP)入门

零.先修课程 首先,在开始理解DP的思想前,你需要 1. 完成HDU里面的递推求解专题练习(For Beginner)那7道题(这些题很简单,题解请在博客中搜索),这对你理解DP有很大的帮助. 2. 对递归搜索(比如深度优先搜索,DFS)有一定了解. 一.递归与记忆化搜索 我们从POJ 3176入手来学习这一思想.(题目很短,请快速读完) 从上往下看,最大和值无非是往左走和往右走这两条路的较大者.这样,我们可以写出下面这个重要的递归函数:(这里i表示行,j表示列) int f(int i, in

用动态规划算法对最大子串问题的java实现

最大字串问题描述大概就是给定2个字符串,找出他们两个共有的最长字符串.比如一个是"tabcfg"另外一个"abckj"那么最大子串就是"abc". 动态规划算法最重要的就是分解问题,找出递归.说一下我的思考思路,首先拿到2个字符串,如何找到最长子串呢? 1.假设他们(字符串a,b)的头字母不相同的话,那么分别去掉首字母比较,也就是说用a.subString(1)和b比较,用 b.subString(1)和a比较,最长子字符串没变吧?答案是肯定的.

milk香港版——交互设计漫谈

当产品相对稳定与可控,小神有愿望快速记录这个项目. 内容涉及小神参与产品设计与执行的过程,由交互/视觉设计层面的需求分析.功能设计与设计执行组成. 与其带入一些工作中的设计技巧,小神更愿意分享其中的设计思想与理念憧憬. 设计之所以不同于美化,是因为前者被赋予了驱动的灵魂. 背景 milk香港版,内部命名"milk mobile".是香港潮流杂志<milk>在移动新领域的合作尝试.目标设备为主流的中高端便携移动设备,iPhone/iPod touch/Android Phon