zoukankan      html  css  js  c++  java
  • 机器人小Q

    绿题好难啊

    luoguP1687

    。。。。注释写在代码里了。

    既然是求最小的天数,应该以天数作为DP值,剩下的变量里挑选合适的作为数组下表(数据范围可能会有提示)

    第一层循环是选到了第i个物品,当前是第i个物品。那么到当前的dp[i][]就是对于前i个物品的答案。
    对于一个当前的i,它指我们正在考虑这个第i个物品对答案的影响。
    i要结合j理解,i是当前要拿全部物品中的第i个.而j循环显然是,我们上一个拿的物品是选中的m个中的第j-1个,j一定小于m,并且,从前到后的顺序来看,j肯定是在i之前的(j肯定小于等于i),故取min(m,i)。

    /*定义一个dp[j][k]表示从前开始,拿到了第j个了,
    当前最后一个背包剩下k的空间,此时的最小背包数量
    转移分两种,一个是当前背包还能塞下第j个就塞,
    一个塞不下了,新开一个背包,枚举当前背包的剩余空间,转移。
    */ 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    using namespace std;
    const int N = 3005;
    int n,m,f[N][200],a[N],minn[N];
    inline int read()
    {
    	char c=getchar();
    	int ans=0,w=1;
    	while((c<'0'||c>'9')&&c!='-') c=getchar();
    	if(c=='-') { w=-1; c=getchar(); }
    	while(c>='0'&&c<='9')
    	{ ans=ans*10+c-'0'; c=getchar(); }
    	return ans*w;
    }
    int main() 
    {
    	n=read(); m=read();
    	for(re int i=1;i<=n;i++)
    	 a[i]=read();
    	memset(f,0x7f,sizeof(f));
    	if(n<m)
    	{ printf("You can't do it.
    "); return 0;}
    	f[0][119]=1;//
    	for(re int i=1;i<=n;i++) //在前i个物品中  
    	 for(re int j=min(m,i);j>=1;j--)//
    	 {//原理同01背包的倒序  
    	 	for(re int k=0;k<=119-a[i];k++)//
    	 	 f[j][k]=min(f[j][k],f[j-1][k+a[i]]);//在原来的背包中添 
    	 	for(re int k1=a[i]-1;k1>=0;k1--)
    	 	 f[j][119-a[i]]=min(f[j][119-a[i]],f[j-1][k1]+1);//新加一个背包 
    	 }
    	int ans=0x3f3f3f3f;
    	for(int i=0;i<=119;i++)
    	 ans=min(f[m][i],ans);
    	printf("%d
    ",ans);
    	return 0;
    } 
    
  • 相关阅读:
    [solr]
    [solr]
    [Linux] CentOS 加入开机启动
    [Linux] VirtualBox
    [Eclipse]
    [JBoss]
    [solr]
    [solr]
    [solr]
    [solr]
  • 原文地址:https://www.cnblogs.com/karryW/p/10827757.html
Copyright © 2011-2022 走看看