USACO3.1 Stamps(stamps)

        动态规划题,隐式二维费用背包,设s[i]表示输入的邮票面值,d[k]表示贴出k邮资所需要的邮票的最少张数。于是动态转移方程:d[j+s[i]]=min{d[j+s[i]],d[j]+1}。对j:0~mm*m,i:0~n-1,求每一对组合(j,i)决定的d[j+s[i]]的最小值,最后d[k]的值就是贴出k邮资所需邮票数量的最小值。注意初始化,除了d[0]=0,其他都初始化为10000。

/*
ID:jzzlee1
PROB:stamps
LANG:C++
*/
//#include<iostream>
#include<fstream>
using namespace std;
ifstream cin("stamps.in");
ofstream cout("stamps.out");
short d[2010000];int s[200];
int main()
{
	int i,j,m,n,mm=0,ans=0;
	cin>>m>>n;
    for (i=0;i<n;++i)
	{
		cin>>s[i];
		if(mm<s[i])
			mm=s[i];
    }
    for(i=1;i<=mm*m+3;++i)
		d[i]=10000;
	for (j=0;j<=mm*m;++j)
		 for (i=0;i<n;++i)
			if(d[j]<m&&d[j+s[i]]>1+d[j])
				d[j+s[i]]=1+d[j];
    while (d[ans+1]<=m)
		++ans;
	cout<<ans<<endl;
	return 0;
}

你可能感兴趣的:(USACO)