Codeforces Round #214 (Div. 2)(揹包變形)
A. Dima and Guards
只需要比較一下,守衛的最小要求的和與給定值的大小即可
#include<iostream>
#include<cstdio>
using namespace std;
int n,x1,y1,x2,y2;
int who,choc,juice;
bool can(int x,int y)
{
return x+y<=n;
}
int main()
{
cin>>n;
bool flag=false;
for(int i=1;i<=4;i++)
{
cin>>x1>>y1>>x2>>y2;
if(!flag)
{
if(can(x1,x2)){choc=x1,juice=n-choc;flag=true;}
else if(can(x1,y2)){choc=x1;juice=n-choc;flag=true;}
else if(can(y1,x2)){choc=y1;juice=n-choc;flag=true;}
else if(can(y1,y2)){choc=y1,juice=n-choc;flag=true;}
if(flag) who=i;
}
}
if(flag)
cout<<who<<" "<<choc<<" "<<juice<<endl;
else cout<<-1<<endl;
return 0;
}
B. Dima and To-do List
表示沒太看懂。。。只需要從1到k迴圈就行了
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=100010;
const int INF=1000000000;
int a[2*maxn];
int N,K;
int main()
{
scanf("%d%d",&N,&K);
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
int max1=INF,sum=0,ans;
for(int i=1;i<=K;i++)
{
sum=0;
for(int j=0,k=i;j<N/K;k+=K,j++)
{
sum+=a[k];
}
if(sum<max1){max1=sum,ans=i;}
}
cout<<ans<<endl;
}
C. Dima and Salad
沒想到需要這樣變形,看了別人的題解,才明白過來
題意:就是給了你兩個陣列:a陣列和b陣列,然後讓你從a陣列中選取一個的子序列,子序列的和為sum1,然後除以相應b陣列子序列的和sum2,sum1/sum2剛好為k,讓你求出滿足要求的a陣列中sum1最大為多少,如果不存在這樣的子序列,那麼就輸出-1,否則輸出a陣列中最大的sum1。
分析:對於這道題,我感悟還是比較深的,當時我想到用dp去做,並且抓住了兩個陣列加起來的和分別最多為10000,當時我沒有把題目中的那個式子做變形,所以只想到了去記錄a陣列子序列相加之後的狀態,但是如果a陣列子序列的一個狀態對應有多個b陣列序列的狀態呢?想到了這裡,我就沒法想下去了,因為我無法想到一個好的方法去解決這個問題,後來比完賽之後去看了下別人的程式碼,他們是把式子變形之後,把a[i]-b[i]*k作為狀態進行dp的,這樣a陣列的序列和b陣列的序列就繫結在一起了,就沒必要去考慮我出現的問題了,而他的狀態變化範圍是:-10000-10000,出現了為負數的狀態,無法用陣列實現,於是乾脆把所有狀態都加上10000,於是狀態的變化範圍就變成:0-20000,那麼現在就可以在此基礎上進行dp了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 300005
#define mod 1000000007
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
int n,m,ans,k,flag,cnt;
int a[maxn],b[maxn];
int w[maxn];
int dp[MAXN];
bool solve()
{
int i,j;
memset(dp,-INF,sizeof(dp));
dp[10000]=0;
for(i=1; i<=n; i++)
{
if(w[i]>=0)
{
for(j=20000; j>=w[i]; j--)
{
if(dp[j-w[i]]!=-INF) dp[j]=max(dp[j],dp[j-w[i]]+a[i]);
}
}
else
{
for(j=0;j<20000;j++)
{
if(dp[j-w[i]]!=-INF) dp[j]=max(dp[j],dp[j-w[i]]+a[i]);
}
}
}
ans=dp[10000];
if(ans==0) return false ;
return true ;
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&k))
{
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(i=1; i<=n; i++)
{
scanf("%d",&b[i]);
}
for(i=1; i<=n; i++)
{
w[i]=a[i]-k*b[i];
}
if(solve()) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}
D. Dima and Trap Graph
思路:列舉每條邊,並查集維護,每次加進去右端點大的邊判斷1和n是不是已聯通,更新最大值
下面是並查集的程式碼:
這個題看人家寫的還可以列舉左端點,二分右頂點,dfs判斷。
下面是程式碼:
思路:列舉每條邊,並查集維護,每次加進去右端點大的邊判斷1和n是不是已聯通,更新最大值
下面是並查集的程式碼:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxm=3010;
const int maxn=1010;
struct node
{
int a,b,l,r;
};
int pre[maxn];
int n,m;
bool cmp(node a,node b)
{
return a.r>b.r;
}
void init()
{
for(int i=0;i<=n;i++)
{
pre[i]=i;
}
}
int find(int x)
{
if(pre[x]==x) return x;
return pre[x]=find(pre[x]);
}
void unite(int a,int b)
{
int x=find(a);
int y=find(b);
pre[x]=y;
}
int main()
{
node edge[maxm];
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
cin>>edge[i].a>>edge[i].b>>edge[i].l>>edge[i].r;
sort(edge,edge+m,cmp);
int ans=-1;
for(int i=0;i<m;i++)
{
init();
int min1=edge[i].r;
for(int j=0;j<m;j++)
{
if(edge[j].l>edge[i].l) continue;
unite(edge[j].a,edge[j].b);
min1=min(min1,edge[j].r);
int x=find(1);
int y=find(n);
if(x==y) {ans=max(ans,min1-edge[i].l+1);break;}
}
}
if(ans<=0)
cout<<"Nice work, Dima!"<<endl;
else
cout<<ans<<endl;
return 0;
}
這個題看人家寫的還可以列舉左端點,二分右頂點,dfs判斷。
下面是程式碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1005
#define MAXN 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m,ans,cnt,ii,cxx,flag;
int pp[MAXN];
bool vis[MAXN];
int x[MAXN];
struct Node
{
int v,next;
int a,b;
} edge[MAXN];
void addedge(int u,int v,int a,int b)
{
cnt++;
edge[cnt].v=v;
edge[cnt].a=a;
edge[cnt].b=b;
edge[cnt].next=pp[u];
pp[u]=cnt;
}
void dfs(int u,int le,int ri)
{
if(flag) return ;
if(u==n)
{
flag=1;
return ;
}
int i,j,v;
for(i=pp[u]; i; i=edge[i].next)
{
v=edge[i].v;
if(!vis[v]&&le>=edge[i].a&&ri<=edge[i].b)
{
vis[v]=1;
dfs(v,le,ri);
}
}
}
void solve()
{
int i,j,u,v,t;
int le,ri,mid;
ans=0;
for(i=1;i<=cxx;i++)
{
le=x[i],ri=1000001;
while(le<ri)
{
mid=(le+ri)>>1;
flag=0;
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs(1,x[i],mid);
if(flag) le=mid+1;
else ri=mid;
}
ans=max(ans,le-x[i]);
}
}
int main()
{
int i,j;
int u,v,a,b;
while(~scanf("%d%d",&n,&m))
{
cnt=cxx=0;
memset(pp,0,sizeof(pp));
for(i=1; i<=m; i++)
{
scanf("%d%d%d%d",&u,&v,&a,&b);
x[++cxx]=a;
x[++cxx]=b;
addedge(u,v,a,b);
addedge(v,u,a,b);
}
solve();
if(ans) printf("%d\n",ans);
else printf("Nice work, Dima!\n");
}
return 0;
}
相關文章
- Codeforces Round #360 (Div. 2) E dp 類似01揹包
- Codeforces Round #639 (Div. 2)
- Codeforces Round #541 (Div. 2)
- Codeforces Round #682 (Div. 2)
- Codeforces Round #678 (Div. 2)
- Codeforces Round #747 (Div. 2)
- Codeforces Round #673 (Div. 2)
- Codeforces Round #672 (Div. 2)
- Codeforces Round #448 (Div. 2) A
- Codeforces Round #217 (Div. 2)
- Codeforces Round #256 (Div. 2)
- Codeforces Round #259 (Div. 2)
- Codeforces Round #257 (Div. 2)
- Codeforces Round #258 (Div. 2)
- Codeforces Round #171 (Div. 2)
- Codeforces Round #173 (Div. 2)
- Codeforces Round 932 (Div. 2)
- Codeforces Round 934 (Div. 2)
- Codeforces Round 940 (Div. 2)
- Codeforces Round 973 (Div. 2)
- Codeforces Round 960 (Div. 2)
- Codeforces Round 958 (Div. 2)
- Codeforces Round 961 (Div. 2)
- Codeforces Round 948 (Div. 2)
- Codeforces Round 945 (Div. 2)
- Codeforces Round 951 (Div. 2)
- Codeforces Round 955 (Div. 2)
- Codeforces Round 953 (Div. 2)
- Codeforces Round 873 (Div. 2)
- Codeforces Round 969 (Div. 2)
- Codeforces Round 949 (Div. 2)
- Codeforces Round 965 (Div. 2)
- Codeforces Round 963 (Div. 2)
- Codeforces Round 967 (Div. 2)
- Codeforces Round 975 (Div. 2)
- Codeforces Round 976 (Div. 2)
- Codeforces Round 972 (Div. 2)
- Codeforces Round 979 (Div. 2)