[U]3.1.6 Stamps 会错意的DP题

3章第一节有道题敲不出来啊~~~没办法,只能把后面的题先给敲咯~

这个题呢...

首先本巨菜想了一个很傻很水很烂的DP方程。使得自己的程序果断崩了...

[U]3.1.6 Stamps 会错意的DP题_第1张图片

开了一个10001*200的二维boolean数组,[面额][张数]这样来DP,因为最大的面额只有10000 ,再通过循环数组的方法,勉强使得空间不爆掉,结果过了9个点,第10个点果断超时。

后来牌桌子一想!可以变成一维DP!a[面额]保存的值为最小张数;

a[i]=min( a[i],a[i-面额]+1 );

这样就很好的A掉了。速度还行。

/*
ID:bysen
LANG:C++
PROG:stamps
*/
#include<stdio.h>
#define INF 0x0FFFFFFF
using namespace std;

int re[10001];
//DP数组记录构成当前面额最小的邮票枚数 
int v[201];

int min( int a,int b ){ return a<b?a:b; }

int main()
{
 	freopen( "stamps.in","r",stdin );
 	freopen( "stamps.out","w",stdout );
 	int k,n;
 	for( int i=0;i<10001;i++ )
 		 re[i]=INF;
 	
 	scanf( "%d %d",&k,&n );
 	
	for( int i=0;i<n;i++ )
	{
 		 scanf( "%d",&v[i] );
 		 re[v[i]]=1;
    }
    
    int top=v[0];
    while( true )
    {
	 	   top++;
	 	   if( top>10001 )
	 	   	   re[top%10001]=INF;
	 	   	   
	 	   for( int i=0;i<n;i++ )
	 	   		if( top-v[i]>0 )
	 	   			re[top%10001]=min( re[top%10001],re[(top-v[i]+10001)%10001]+1 );
	   		if( re[top%10001]>k )
	   			break;
    }
    printf( "%d\n",top-1 );
 	return 0;
}


你可能感兴趣的:([U]3.1.6 Stamps 会错意的DP题)