【USACO3.1.6】邮票 动态规划/滚动数组

51 篇文章 0 订阅
bool类型:f[i][j]  i这个数额,由j个邮票贴成 是否可行。  f[i][j] = { f[i - p][j - 1] 其中有一个是true即可,p为邮票面额}






换一个思路


f[i]  i这个数额,最少由几张邮票组成。


f[i] = min{f[i - p]} + 1    其中i的数额最高可以到达 pk也就是10000*200=2000000的空间和时间其实都是很大了。 再加上每次转移是O(k),还是会TLE。


但是这里我只需要找一些数字,也就是只有用到f[i-p],而在f数组更靠前的地方,其实是用不到那些空间了。那么可以在这里考虑到空间优化,优化到O(10000)的空


间。
这就是无压力可以接受的了。


接下来是转移的问题。


假如有1,2,5 这几个面额。 对于  10而言,可以从9,8,5转移。从f[9] f[8] f[5]找一个最小值。 接下来是从f[6] f[9] f[10]找最小值…… 貌似没有什么可以优化


的,虽然是找最小值,但是并不是区间上的最小值查找,而且不具有连续性,所以貌似不好用堆或者线段树来解决……


最终时间复杂度

2000000 * 50 = 10000000 = 10^8  应该不会TLE。 但是这么不优秀的算法,我实在不开心啊……



Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.005 secs, 3416 KB]
   Test 2: TEST OK [0.003 secs, 3416 KB]
   Test 3: TEST OK [0.003 secs, 3416 KB]
   Test 4: TEST OK [0.003 secs, 3416 KB]
   Test 5: TEST OK [0.003 secs, 3416 KB]
   Test 6: TEST OK [0.000 secs, 3416 KB]
   Test 7: TEST OK [0.005 secs, 3416 KB]
   Test 8: TEST OK [0.005 secs, 3416 KB]
   Test 9: TEST OK [0.008 secs, 3416 KB]
   Test 10: TEST OK [0.057 secs, 3416 KB]
   Test 11: TEST OK [0.467 secs, 3416 KB]
   Test 12: TEST OK [0.100 secs, 3416 KB]
   Test 13: TEST OK [0.005 secs, 3416 KB]

All tests OK.


只用了3M的空间~~~ 这点倒是我很满意的地方啦啦啦啦啦啦啦啦~~~~



/*
TASK:stamps
LANG:C++
*/

#include <cstdio>

#define INF 10000
#define min(a, b) ((a)<(b)?(a):(b))
#define size 13000
int K, N;
int a[50];
int f[size]={0}, now=0, ans=0, tmp, minnum;

int main()
{
	freopen("stamps.in","r",stdin);
	freopen("stamps.out","w",stdout);
	scanf("%d%d", &K, &N);
	for (int i = 0; i != N; ++ i)	scanf("%d", a + i);
	for (int i = 1; i != size; ++ i)	f[i] = INF;
	while (1)
	{
		++ ans;	
		++ now;
		now %= size;
		minnum = INF;
		for (int i = 0; i != N; ++ i)
		{
			tmp = (now - a[i]);	
			tmp < 0 ? tmp += size : tmp;
			if (f[tmp] == INF)	continue;
			minnum = min(minnum, f[tmp]);
		}
		if (minnum >= K)	break;
		f[now] = minnum + 1;
	}
	printf("%d\n", ans - 1);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值