社区讨论

简单 DP 求调悬关,对拍无果

UVA323Jury Compromise参与者 3已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@m344wsh9
此快照首次捕获于
2024/11/05 15:34
去年
此快照最后确认于
2025/11/04 15:18
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
void file(){
//	freopen("shuju.in","r",stdin);
//	freopen("UVA323.out","w",stdout);
}
int n,m,test;
int dp[205][25][405][2];
int p[205],d[205],a[205];
void print(int i,int j,int k,int fu){
	if(i==0||j==0)return;
	if(fu==1){
		if(dp[i-1][j][k][1]==dp[i][j][k][1])print(i-1,j,k,1);
		else {
			a[j] = i;
			int x = d[i]-p[i];
			int y = k-x;
			if(y<0){
				print(i-1,j-1,abs(y),0);
			}else {
				print(i-1,j-1,y,1);
			}
		}
	}else {
		if(dp[i][j][k][0]==dp[i-1][j][k][0])print(i-1,j,k,0);
		else {
			a[j] = i;
			int x = d[i]-p[i];
			int y = -k-x;
			if(y<0){
				print(i-1,j-1,abs(y),0);
			}else {
				print(i-1,j-1,y,1);
			}
		}
	}
	
}
signed main(){
	/* int*int 开long long*/
	/*开 long long 注意空间是否爆炸*/
	/*检查数组是否越界*/
	/*dfs能加剪枝就加剪枝*/
	/*对于精度误差的检查时需要加绝对值*/
	/*尽量不用memset*/
	file();
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	while(n!=0&&m!=0){
		test++;
		for(int i = 1;i<=n;i++)cin >> p[i] >> d[i];
		for(int i = 0;i<=n;i++){
			for(int j = 0;j<=m;j++){
				for(int k = 0;k<=400;k++){
					dp[i][j][k][1]=dp[i][j][k][0]=-1000000000;
				}
			}
		}
		dp[0][0][0][0]=dp[0][0][0][1]=0;
		for(int i=1;i<=n;i++){
			dp[i][0][0][0]=dp[i][0][0][1]=0;
			for(int j=1;j<=min(i,m);j++){
				for(int k = 0;k<=400;k++){
					dp[i][j][k][1] = dp[i-1][j][k][1];
					dp[i][j][k][0] = dp[i-1][j][k][0];
					int x = d[i]-p[i];
					int y = k-x;
					if(y<0)dp[i][j][k][1]=max(dp[i][j][k][1],dp[i-1][j-1][abs(y)][0]+d[i]+p[i]);
					else dp[i][j][k][1]=max(dp[i][j][k][1],dp[i-1][j-1][y][1]+d[i]+p[i]);
					y = -k-x;
					if(y<0)dp[i][j][k][0]=max(dp[i][j][k][0],dp[i-1][j-1][abs(y)][0]+d[i]+p[i]);
					else dp[i][j][k][0]=max(dp[i][j][k][0],dp[i-1][j-1][y][1]+d[i]+p[i]);
				}
			}
		}
		int ans = 0,ans2 = 0;
		for(int k = 0;k<=400;k++){
			bool ok = 0;
			if(dp[n][m][k][1]>=0){
				ans = dp[n][m][k][1];
				ans2=k;
				ok = 1;
			}
			if(dp[n][m][k][0]>=ans){
				ans = dp[n][m][k][0];
				ans2 = -k;
				ok = 1;
			}
			if(ok)break;
		}
		int D = (ans+ans2)/2;
		int P = ans - D;
		cout << "Jury #" << test<<"\n";
		cout << "Best jury has value " << P <<" for prosecution and value " <<D<<" for defence:\n";
		if(ans2>0)print(n,m,ans2,1);
		else print(n,m,abs(ans2),0);
		for(int i = 1;i<=m;i++)cout << " " << a[i];
		cout << "\n\n";
		cin >> n >> m;
	}
}

回复

5 条回复,欢迎继续交流。

正在加载回复...