动规求调
查看原帖
动规求调
368791
FL_sleake楼主2023/12/31 18:09

rt,马蜂不好因为已经改了 nn 次了...

双倍经验过了。

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
#include<cstdio>
#include<cmath>
#include<string.h> 
using namespace std;
#define int long long
int n,h,t[30],f[30],d[30],dp[30][210],ans[30][210];
int getans(int id,int t){
	/*
	int num=0;
	for(int i=0;i<t;i++) num+=max(0ll,f[id]-i*d[id]);
	return num;
	*/
	if(d[id]==0) return f[id]*t;
	int num=max(f[id]%d[id],f[id]-(t-1)*d[id]);
	return (num+f[id])*((f[id]-num)/d[id]+1)/2;
}
signed main(){
	while(1){
		memset(ans,0,sizeof(ans));
		memset(dp,-0x3f,sizeof(dp));
		cin>>n;
		if(!n) break;
		cin>>h;
		h*=12;
		for(int i=1;i<=n;i++) cin>>f[i];
		for(int i=1;i<=n;i++) cin>>d[i];
		t[1]=0;
		dp[0][0]=0;
		for(int i=2;i<=n;i++) cin>>t[i];
		for(int i=1;i<=n;i++){
			for(int j=t[i];j<=h;j++){
				for(int k=0;k<=j-t[i];k++){
					if(dp[i-1][k]+getans(i,j-k-t[i])>=dp[i][j]){
						dp[i][j]=dp[i-1][k]+getans(i,j-k-t[i]);
						//cout<<i<<","<<j<<","<<dp[i][j]<<endl;
						ans[i][j]=j-k-t[i];
					}
				}
			}
		}
		int num=0,x=0,y=h,add=0;
		for(int i=1;i<=n;i++) if(dp[i][h]>num) num=dp[i][h],x=i;
		vector<int> cnt;
		for(int i=n;i>x;i--) cnt.push_back(0);
		for(int i=1;i<=x;i++) add+=t[i];
		while(x){
			cnt.push_back(ans[x][y]);
			y=(y-ans[x][y]-t[x]);
			x--;
		}
		for(int i=0;i<cnt.size();i++) add+=cnt[i];
		add=h-add;
		//cout<<"add="<<add<<endl;
		cout<<num<<endl;
		for(int i=cnt.size()-1;i>=0;i--){
			int o=cnt[i];
			if(i==cnt.size()-1) o+=add;
			cout<<o*5;
			if(i) cout<<", ";
		}
		cout<<endl;
		cout<<"Number of fish expected: "<<num<<endl;
	}
	return 0;
}
/*
10
5
81 138 84 124 91 68 131 131 144 90
13 18 14 11 17 10 15 15 16 12
10 11 4 6 6 6 7 2 11

2097
*/
2023/12/31 18:09
加载中...