社区讨论
简单 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 条回复,欢迎继续交流。
正在加载回复...