USACO 3.1 Stamps

动态规划题。开始的时候用状态dp[i][j]表示最多i张邮票,能否组成j元。这样时间复杂度为O(n*n*k*10000)结果TLE了。
先贴个TLE的代码:
#include <iostream>
#include 
<fstream>

using namespace std;

ifstream fin(
"stamps.in");
ofstream fout(
"stamps.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

int k,n;
bool dp[200*10000+1];
int stamps[50];

void solve()
{
    
in>>k>>n;

    
for(int i=0;i<n;++i)
        
in>>stamps[i];

    sort(
&stamps[0],&stamps[n]);

    
int maximum = stamps[n-1]*k;

    dp[
0= true;
    
for(int i=0;i<k;++i){
        
for(int j=maximum;j>=0;j--){
            
if(!dp[j])
            
for(int x=0;x<n;++x){
                
if(j>=stamps[x]&&dp[j-stamps[x]]){
                    dp[j]
=true;
                    
break;
                }
            }
        }
    }

    
int res;
    
for(res=1;res<=maximum&&dp[res];++res);

    
out<<res-1<<endl;
}

int main(int argc,char *argv[])
{
    solve(); 
    
return 0;
}


后来实在想不出来如何优化了。。。看了下去年自己写的代码...Orz..
用dp[i]表示组成i所需要的最少的邮票数。这样当dp[i]>k时,说明不能用k张邮票组成i了。时间复杂度为O(10000*k*n)。
代码如下:

#include <iostream>
#include 
<fstream>

using namespace std;

ifstream fin(
"stamps.in");
ofstream fout(
"stamps.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

int k,n;
int dp[200*10000+2];
int stamps[50];

void solve()
{
    
in>>k>>n;

    
for(int i=0;i<sizeof(dp)/sizeof(int);++i)
        dp[i] 
=1000; //1000用作表示infinite足够了,因为k<=200.用INT_MAX表示无穷大,加一个数的时候会溢出

    
for(int i=0;i<n;++i){
        
in>>stamps[i];
    }

    sort(
&stamps[0],&stamps[n]);

    
int maximum = stamps[n-1]*k;

    dp[
0]=0;

    
for(int i=0;i<n;++i)
        
for(int j=stamps[i];j<=maximum;++j){      
               dp[j] 
=min(dp[j],dp[j-stamps[i]]+1);
        }

    
for(int i=1;i<=maximum;++i){
        
if(dp[i]>k){
            
out<<i-1<<endl;
            
return;
        }
    }

    
out<<maximum<<endl;
}

int main(int argc,char *argv[])
{
    solve(); 
    
return 0;
}


posted on 2009-06-30 20:37 YZY 阅读(1529) 评论(8)  编辑 收藏 引用 所属分类: AlgorithmUSACO动态规划

评论

# re: USACO 3.1 Stamps 2009-07-01 08:55 Kevin Lynx

不要再在首页发布这些东西了。基本上只有代码,不知道发首页的目的是什么。我的RSS READER订阅了CPPBLOG首页,但全是你的东西。  回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-01 08:59 kuailekaba

就是,别发了,全是代码,没人看的!  回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-01 09:09 YZY

@Kevin Lynx
:-). 不好意思,以后不发首页了吧。貌似cppblog中做算法的人不多  回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-01 17:58 Khan's Notebook

不是做算法的人多少问题
你给一个答案之前都要让人知道问题是什么吧.   回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-01 22:22 Contax

其实内容还行,但是建议你把答案贴上去的时候,把题目也附上,否则实在不知所云  回复  更多评论   

# re: USACO 3.1 Stamps[未登录] 2009-07-02 09:06 YZY

@Contax
题目就是USACO啊。。USACO是美国给高中生的一个OI训练题库。网上搜一下USACO就知道了。  回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-02 21:11 Contax

怎么说呢,您的博客我有时候也看,也会去网上搜题目,不过如果你能把题目也附上的话,能节约所有人找题目的时间,而且作者把题目附上的时间比其他大多数人找题目的时间要少得多吧(本来题目就在手上)。

细节决定成败,个人仅仅以工程的角度来看待这个问题,相信楼上的抱怨和我是一样的心情。  回复  更多评论   

# re: USACO 3.1 Stamps 2009-07-02 22:02 YZY

@Contax
呵呵,你说的也有道理,以前我也附过题目,后来就懒得添加了。毕竟题目一般挺长的,添加上后面也不是很好看。附链接的话,是需要usaco的账号才能打开的。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜