设为首页 加入收藏

TOP

zoj 3631 Watashi's BG (一)
2015-11-21 01:17:58 来源: 作者: 【 】 浏览:7
Tags:zoj 3631 Watashi'

题目大意:

有n(1~30)天,第i天花费vi(1~10^8),总钱数m(0~10^8)。

每天可以选择花费或不花费。

问最多能花多少钱。

?

题目思路:

题意和01背包差不多,不过01背包会爆掉O(nm),复杂度太高了,而且数组也开不下。

因为n只有30,所以试着用深搜+剪枝。

设当前的累加花费为tot,当前为第i天,mmin[i]表示i~n中的最小值,sum[i]表示a[i]+...+a[n],ret表示当前最优值。

剪枝一:tot>m,显然后面都不需要访问了。

剪枝二:tot+sum[i]<=ret,显然后面不会出现比当前最优值更优的了。

剪枝三:tot+mmin[i]>m,显然后面的值无论怎么加是不合法的。

剪枝四:tot+sum[i]<=m,显然后面访问后可达的最优值为tot+sum[i]了。(这个做题的时候没发现)

剪枝五:ret==m,显然不可能出现更优的了,也不需要访问了。

?

我是用了剪枝(1,2,3,5)才过了,不过不知道为什么有的人用(1,2,5)就过了,而且0ms。。

代码也没发现比较奇特的地方。。

?

代码:

[cpp]?
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
#include ??
using namespace std;?
?
#define ll __int64??
#define ls rt<<1??
#define rs ls|1??
#define lson l,mid,ls??
#define rson mid+1,r,rs??
#define middle (l+r)>>1??
#define clr_all(x,c) memset(x,c,sizeof(x))??
#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))??
#define eps (1e-8)??
#define MOD 1000000007??
#define INF 0x3f3f3f3f??
#define PI (acos(-1.0))??
#pragma comment(linker, "/STACK:102400000,102400000")??
template T _max(T x,T y){return x>y? x:y;}?
template T _min(T x,T y){return x template T _abs(T x){return (x < 0)? -x:x;}?
template T _mod(T x,T y){return (x > 0)? x%y:((x%y)+y)%y;}?
template void _swap(T &x,T &y){T t=x;x=y;y=t;}?
template void getmax(T& x,T y){x=(y > x)? y:x;}?
template void getmin(T& x,T y){x=(x<0 || y int TS,cas=1;?
const int M=100000+5;?
int n,m,a[33],sum[33],mmin[33],ret;?
?
void dfs(int p,int tot){?
??? if(tot>m || ret==m) return;?
??? ret=_max(ret,tot);?
??? if(p>n || tot+sum[p]<=ret || tot+mmin[p]>m) return;?
??? dfs(p+1,tot+a[p]);?
??? dfs(p+1,tot);?
}?
?
void run(){?
??? int i,j;?
??? for(i=1;i<=n;i++) scanf("%d",&a[i]);?
??? ret=0;?
??? for(i=1,j=m;i<=n && j;i++)?
??????? if(ret+a[i]<=m) ret+=a[i];?
??? sum[n]=mmin[n]=a[n];?
??? for(i=n-1;i>=1;i--) sum[i]=sum[i+1]+a[i];?
??? for(i=n-1;i>=1;i--) mmin[i]=_min(mmin[i+1],a[i]);?
??? dfs(1,0);?
??? printf("%d\n",ret);?
}?
?
void preSof(){?
}?
?
int main(){?
??? //freopen("input.txt","r",stdin);??
??? //freopen("output.txt","w",stdout);??
??? preSof();?
??? //run();??
??? while((~scanf("%d%d",&n,&m))) run();?
??? //for(scanf("%d",&TS);cas<=TS;cas++) run();??
??? return 0;?
}?

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define ll __int64
#define ls rt<<1
#define rs ls|1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define middle (l+r)>>1
#define clr_all(x,c) memset(x,c,sizeof(x))
#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))
#define eps (1e-8)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#pragma comment(linker, "/STACK:102400000,102400000")
template T _max(T x,T y){return x>y? x:y;}
template T _min(T x,T y){return x template T _abs(T x){return (x < 0)? -x:x;}
template T _mod(T x,T y){return (x > 0)? x%y:((x%y)+y)%y;}
template void _swap(T &x,T &y){T t=x;x=y;y=t;}
template void getmax(T& x,T y){x=(y > x)? y:x;}
template void getmin(T& x,T y){x=(x<0 || y int TS,cas=1;
const int M=100000+5;
int n,m,a[33],sum[33],mmin[33],ret;

void dfs(int p,int tot){
?if(tot>m || ret==m) return;
?ret=_max(ret,tot);
?if(p>n || tot+sum[p]<=ret || tot+mmin[p]>m) return;
?dfs(p+1,tot+a[p]);
?dfs(p+1,tot);
}

void run(){
?int i,j;
?for(i=1;i<=n;i++) scanf("%d",&a[i]);
?ret=0;
?for(i=1,j=m;i<=n && j;i++)
??if(ret+a[i]<=m) ret+=a[i];
?sum[n]=mmin[n]=a[n];
?for(i=n-1;i>=1;i--) sum[i]=sum[i+1]+a[i];
?for(i=n-1;i>=1;i--) mmin[i]=_min(mmin[i+1],a[i]);
?dfs(1,0);
?printf("%d\n",ret);
}

void preSof(){
}

int main(){
??? //freopen("input.txt","r",stdin);
??? //freopen("output.tx

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 4153(数学) 下一篇C++运算符+,+=,<<,=重载..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: